Is it currently possible to override the structure constructor in Fortran?
sayılı:
type(mytype) function init_mytype
integer, intent(in) :: i
belki de yeniden yazılmalıdır fonksiyon şartnamede, bulunmaz varlığını ve bir argüman hedefi belirler Yaklaşımınızı kullanmak bile, kurucu geçersiz kılma ile ilgili değildir. Ana nedeni yapı kurucusu # OOP kurucusudur. Bazı benzerlikler var ama bu sadece başka bir fikir.
Başlangıcı olmayan işlevinizi başlatma ifadesinde kullanamazsınız. Yalnızca sabit, dizi veya yapı yapıcı, içsel işlevler kullanabilirsiniz ... Daha fazla bilgi için Fortran 2003 taslağında 7.1.7 Başlatma ifadesine bakın. Tamamen
type(mytype) :: x
x = mytype(0)
ve
type(mytype) :: x
x = init_mytype(0)
ve ne mymod MODÜLÜ içindeki ARAYÜZ bloğunu kullanarak tüm noktasıdır arasındaki gerçek fark nedir anlamıyorum dikkate gerçeğinden hareketle
.
Açıkçası, dürüstçe bir fark var, büyük olanı - ilk yol yanıltıcıdır. Bu işlev yapıcı değildir (çünkü Fortran'da hiçbir OOP kurucusu yoktur), bir başlatıcıdır.
- Bellek tahsisi: Ana akım cepten Yapıcıda
sırayla iki şey yapıyor sorumludur.
- Üye başlatma.
Farklı dillerdeki bazı örnek sınıf örneklerine bir göz atalım.
Java
yılında: MyType mt = new MyType(1);
çok önemli bir gerçeği gizlenmiştir - nesne aslında bir sınıf türünde bir varibale bir göstericidir gerçeğini.
MyType* mt = new MyType(1);
Ama
her iki dilde bir iki kurucu görevleri bile sözdizimi düzeyinde yansıtılmasını görebilirsiniz: C++ eşdeğer kullanarak yığın üzerinde
tahsisi olacaktır. İki bölümden oluşur: anahtar kelime yeni (tahsis) ve yapıcı adı (başlatma). Objective-C sözdiziminde bu gerçeği daha da vurgulanmaktadır: MyType* mt = [[MyType alloc] init:1];
Çoğu zaman, ancak, yapıcı çağırma diğer bazı formunu görebilirsiniz. Yığın C tahsisi durumunda ++ aslında biz sadece bunu düşünmüyoruz böylece yanıltıcı özel (çok kötü) sözdizimi inşaatı
MyType mt(1);
kullanır.
Python
mt = MyType(1)
hem nesne aslında bir işaretçi ve tahsis sürüyorsunuz ilk (sözdizimi düzeyinde) gizli olmasıdır gerçeği yılında. Ve bu yöntem denir ... __init__
! O_O Yanıltıcı. С ++ yığın tahsisi bununla karşılaştırıldığında kaybolur. =)
Neyse, dilde yapıcısı fikri yönteminin bazı özel tür kullanarak tek deyimi yılında tahsisini bir başlatma yapabilme yeteneğine işaret eder. Ve bunun "gerçek OOP" olduğunu düşünüyorsanız, senin için kötü haberlerim var. Hatta Smalltalkdoesn't have constructors. Sadece sınıflar üzerinde new
yöntemine sahip olmak için bir kuraldır (bunlar meta sınıflarının tekil nesneleridir). Aynı amaca ulaşmak için Factory Design Pattern diğer birçok dilde kullanılmaktadır.
Fortran'daki modüller kavramının Modula-2'den esinlendiği bir yer okudum. Ve bana göre OOP özellikleri Oberon-2'dan ilham alıyor. Oberon-2'de de kurucu yoktur. Ancak elbette, önceden bildirilmiş prosedürün (örneğin, Fortran'daki ALLOCATE gibi, fakat ALLOCATE ifadesidir) saf tahsisi vardır. Tahsis ettikten sonra (pratikte) bazı başlatıcıları arayabilirsin, ki bu sadece sıradan bir yöntem. Orada özel bir şey yok.
Nesneleri başlatmak için bazı fabrikaları kullanabilirsiniz. Tekil nesneler yerine gerçekten modülleri kullandığınız şey bu. Ya da (Java/C#/... programcıların) sıradan işlevler yerine, sıradan işlevler yerine tekil nesneler yöntemlerini kullandıklarını söylemek daha iyidir (hiçbir modül - sıradan işlevlere sahip olmanın yolu yoktur, yalnızca yöntemler).
Ayrıca bunun yerine türüne bağlı SUBROUTINE kullanabilirsiniz. init
altprogramın this
arg için
MODULE mymod
TYPE mytype
PRIVATE
INTEGER :: x
CONTAINS
PROCEDURE, PASS :: init
END TYPE
CONTAINS
SUBROUTINE init(this, i)
CLASS(mytype), INTENT(OUT) :: this
INTEGER, INTENT(IN) :: i
IF(i > 0) THEN
this%x = 1
ELSE
this%x = 2
END IF
END SUBROUTINE init
END
PROGRAM test
USE mymod
TYPE(mytype) :: x
CALL x%init(1)
END PROGRAM
INTENT(OUT)
iyi olacak gibi görünüyor. Çünkü bu yöntemin, tahsis edildikten sonra sadece bir kez ve sağda çağrılmasını bekliyoruz. Bu varsayımın yanlış olmayacağını kontrol etmek iyi bir fikir olabilir. LOGICAL :: inited
için boole bayrağı 'a eklemek için, .false.
olup olmadığını kontrol edin ve ilk başlatma sonrasında .true.
olarak ayarlayın ve yeniden başlatma girişiminde başka bir şey yapın. Google Gruplarında bu konuyla ilgili bir şeyler hatırlıyorum. Bunu bulamıyorum.
Teşekkürler, düzeltildi. Rahatsız edici hata için özür dilerim, bu acele bir örnek oldu. –