2010-03-28 9 views
11

Aşağıdaki C++ programı ile ilgili olarak:Türetilmiş ve temel sınıflar arasında işaretçi-işaretçi dönüşümü?

class Base { }; 

class Child : public Base { }; 

int main() 
{ 
    // Normal: using child as base is allowed 
    Child *c = new Child(); 
    Base *b = c; 

    // Double pointers: apparently can't use Child** as Base** 
    Child **cc = &c; 
    Base **bb = cc; 

    return 0; 
} 

GCC son atamada aşağıdaki hatayı üretir:

error: invalid conversion from ‘Child**’ to ‘Base**’ 

Sorum şu iki bölümden oluşmaktadır:

  1. Neden dolaylı yok Çocuk ** 'dan Base **' ye dönüştürme?
  2. Bu örneği C stili bir döküm veya reinterpret_cast ile çalışabilirim. Bu kalıpları kullanmak, tüm tip güvenliği ortadan kaldırmak demektir. Bu işaretçilerin örtük olarak yayınlanması için sınıf tanımlarına ekleyebileceğim veya en azından dönüştürmeyi yerine static_cast kullanmama izin verecek şekilde bir şey var mı?
+0

Birçok programlama dilinde bu sorudaki varyasyonlar, SO hakkındaki en yaygın sorulardan biridir. Ancak herkes aynı dil için bile biraz farklı ifade eder, bu nedenle çiftleri bulmak zor olabilir. –

+0

Gölgeli atmalardan kaçınmak için bu örneği "düzeltme", neden ilk etapta bir işaretçi-işaretçiyi kullandığınıza bağlı olacaktır. – aschepler

cevap

19

, bu yazabiliriz:

*bb = new Base; 

Ve cBase örneğine işaret sona ereceğini. Kötü.

+0

Küçük düzeltme - '' bb = new Base(); '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'dır diyebilirdi. – Phil

+4

@Phil: 'new',' * Base' türünde bir işaretçi döndürür. 'bb'' ** Base' tipindedir. Böylelikle, 'bb', doğru bir dereğidir. – Amber

+1

Gerekçe, comp.lan.gc 'char **' ve 'char const **' eşdeğerleri hakkında SSS ile aynıdır: http://c-faq.com/ansi/constmismatch.html –