2013-02-11 19 views
5
class a //my base abstract class 
{ 
public: 
virtual void foo() = 0; 
}; 

class b : public a //my child class with new member object 
{ 
public: 
void foo() 
{} 
int obj; 
}; 

int main() 
{ 
b bee; 
a * ptr = &bee; 
ptr->obj; //ERROR: class a has no member named "obj" 
} 

Sorunun yanıtı, "class" işaretçisine sahip olduğum alt sınıfı ("a") işaretçisine sahip olduğumda "obj" üyesine nasıl erişebilirim? ") nesne? Oyuncuların hile yapması gerektiğini biliyorum ama daha iyi çözümler arıyorum.Alt sınıf bir abstact sınıfına işaretçiyi kullanarak alt sınıf üyelerine erişim

+0

Bazı içerikler yardımcı olabilir. Bunu neden yapmak istiyorsun? Yayınlama bir seçenek değilse, türetilmiş sınıfınızda bir sanal işlev geçersiz kılmanız gerekir. Bu, söz konusu üyeye bir referans veya işaretçi döndürür. Bununla birlikte, genellikle kapsülleme kırıyor. Bu, bize temel sınıftaki bir işaretçi aracılığıyla türetilmiş sınıf üyesine erişmek istediğinize geri dönüyor? – Void

+0

@Size muhtemelen haklısınız, tasarımı değiştirmeliyim. – user1873947

cevap

7

b işaretçiyi a işaretçisine b işaretçisine dönüştürmek için dynamic_cast<> işlecini kullanabilirsiniz. Dönüşüm nesnenin çalışma zamanı tip ptrb olduğunu işaret ettiği takdirde başarılı olacaktır ve siz değiştirdikten sonra sonucu kontrol etmeli, böylece, aksi takdirde bir boş gösterici döndürür:

b* p = dynamic_cast<b*>(ptr); 
if (p != nullptr) 
{ 
    // It is safe to dereference p 
    p->foo(); 
} 

Bunu garanti edebilir ptr ile işaret edilen nesnenin türü b'dur, ancak bu durumda (sanal devralma söz konusu olmadığı için) derleme zamanında gerçekleştirildiği için daha az masrafla karşı karşıya olan bir static_cast<> kullanabilirsiniz. GCC ve Clang yılında

b* p = static_cast<b*>(ptr); 
// You are assuming ptr points to an instance of b. If your assumption is 
// correct, dereferencing p is safe 
p->foo(); 
3

Devralma hiyerarşisini düşürmeniz gerekir. Davanız, dynamic_cast'u uygun türüne göre özel olarak üretilmeye uygun hale getirilmiştir; bu durumda, gerçekte aldatmaya çalıştığınız nesne beklenen türdense, tür güvenli bir şekilde kontrol edebilirsiniz.

+0

dynamic_cast hakkında düşünmedim, bu problemi tür güvenli olduğu için çözmelidir. – user1873947

1

auto tip parazitine bile güzel

kullanarak, ayrıca C++ 11 aşağıdaki sözdizimsel toz şeker

if (Base* x = dynamic_cast<Base*>(x)) { 
    // do something with \c x now that we know its defined  
} 

kullanabilir ve içinde (ve Visual Studio) bence

if (auto x = dynamic_cast<Base*>(x)) { 
    // do something with \c x now that we know its defined  
} 

ve nihayet etmek kısıtlamak istiyorsanız salt okunur erişim

if (const auto x = dynamic_cast<Base*>(x)) { 
    // read something from \c x now that we know its defined  
} 
01 Bu güzel içinde için x kapsamını sınırlar

Not eğer if 'S ve else if' s kullanarak birbiri ardına çok sayıda birbirini takip eden dynamic_cast eğer genellikle daha uygundur maddesi (ler).

İlgili konular