2011-01-03 12 views
23

C++ uygulamasında, nesnenin gerçek türünün aynı sınıftan mı yoksa aynı türden mi yoksa türetilmiş mi olduğunu bilmek istiyorum. Bu, aşağıdaki C# koduna benzer:C++ yazımı denetleniyor

Class Base 
{ 
} 

Class Child:Base 
{ 
} 

Base childObject = new Child(); 

If (childObject.GetType() == typeof(Child)) 
{ 
// do some code 
} 

Teşekkürler!

+0

'childObject' türünün türü nedir? Bunu C++'da yapmanın genel bir yolu yoktur, çünkü çalışma zamanında bir tür kavramı yoktur. –

+0

Tamam, ben soru – Homam

+2

düzenleyeyim Ne tür childObject.GetType() hakkında bir şey söylemiş olmasına rağmen, bu kod korkunç, çünkü tür karşılaştırma üzerinde dalları. OOP'un ortadan kaldırması gereken şey budur. –

cevap

48

Bunu yapmanın iki yolu vardır. Öncelikle, nesnenin türü hakkında bilgi içeren type_info yapısını döndüren typeid işlecini kullanabilirsiniz. Eğer typeid(*ptr) kullanmak zorunda ve burada değil typeid(ptr)

Base* ptr = /* ... */ 
if (typeid(*ptr) == typeid(DerivedType)) { 
    /* ... ptr points to a DerivedType ... */ 
} 

Uyarı: Örneğin. typeid(ptr)'u kullanırsanız, Base* için type_info nesnesine geri dönersiniz, çünkü bu işaretçi, ne gösterdiğinden bağımsız olarak Base* türüne sahiptir. Unutulmaması gereken

önemli bir nokta nedir ptr yerleri en tamDerivedType olarak ise bu kontrol edecektir. ptr, DerivedType'dan türeyen bir nesneye işaret ediyorsa (belki EvenMoreDerivedType), bu kod düzgün çalışmayacaktır.

Biraz daha sağlam olan bir tür nesneye işaret edip etmediğinizi kontrol etmenin alternatif bir yolu, dynamic_cast işlecini kullanmaktır. dynamic_cast, çalışma zamanında kontrol edilen bir eşlemeyi gerçekleştirir; bu, satır başarılı olursa ve NULL aksi takdirde geçerli bir işaretçi verecektir. Örneğin:

Bu EvenMoreDerivedType gibi bir şey de ptr eğer noktaları, döküm hala EvenMoreDerivedType devralır, çünkü DerivedType gelen başarılı olacağından avantajına sahiptir
Base* ptr = /* ... */; 
DerivedType* derived = dynamic_cast<DerivedType*>(ptr); 
if (derived) { 
    /* ... points to a DerivedType ... */ 
} 

.

son bir düşünce olarak, bazen böyle bir kod bakın:

Base* ptr = /* ... */ 
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) { 
    /* ... points to a DerivedType ... */ 
} 

Bu if ifadesinin gövdesine derived işaretçisi yerel kapsamları ve sıfırdan farklı değerler C++ true için değerlendirmek gerçeğini kullanır. Kişisel olarak bunu okumayı ve daha az hataya yatkınlığı daha kolay buluyorum, ancak her şey sizin için en kolay olanla birlikte.

Bu yardımcı olur umarız!

+0

Nesnenin bir Temel olup olmadığını bilmek ister, türetilmiş bir sınıf değilse. – Puppy

+0

Ah ... Numune koduyla kafam karışmıştı, bu da işaretçinin bir çocuk tipine işaret edip etmediğini kontrol ediyordu. Geçerli bir nokta. – templatetypedef

2

typeid() öğesini kullanabilirsiniz.

if (typeid(childObject) == typeid(ChildType)) { 
} 

Eğer bu durum doğru döndürürse, bunun alt sınıf olduğunu biliyorsunuzdur.

+2

Ayrıca, çalışma zamanı türü tanımlama (RTTI) etkinleştirilmiş olarak derlemeniz gerektiğinden emin olmanız gerekir. –

+3

Not: Bu **, sadece karşılaştırılan öğenin vtbl içeriyorsa ** çalışır. –

+0

@Billy: Bu doğru - ama temel sınıflarını sanal yıkıcılara vermeyen kim? Sanal işlevler pratik olarak kalıtım noktasıdır. Beklemek mantıksız değil. – Puppy

9

DeadMG'nin cevabı doğru olsa da (birçok kez typid kullandım), bunu posteritlik için dışarı atabileceğimi düşündüm. Nesne yönelimli bir görünümden bunu yapmak için "doğru" yolu:

Class Base 
{ 
    virtual void something() { 
     // probably a no-op, but maybe some default stuff 
    } 
} 

Class Child : public Base 
{ 
    virtual void something() { 
     // do your child-specific code here 
    } 
} 

Base* childObject = new Child(); 
childObject->something(); // does the right thing 
+0

Bu cevabı ikincisiyim. DeadMG'nin cevabı doğru olsa da iyi bir programlama uygulaması olmayabilir ..! –

+0

Nesne için bir şey yapmak istediğinizde bu iyi çalışır. Öte yandan, türlerine bağlı olarak nesneleri işlemek istediğinizde, karmaşık ve sakıncalı hale gelir (tüm bu çift gönderiler ve ziyaretçilerle) –

+0

@ 7vies, true, ancak en yaygın olarak, bu sanal yöntem yaklaşımı en iyi şekilde çalışır ve korumak için en kolay. Dynamic_cast veya typeid'in doğru yaklaşım olduğu zamanlar vardır, ancak bunlar daha nadir durumlardır. – Tim

İlgili konular