2011-04-12 29 views
13

Ben derleme değil Aşağıdaki kod örneği vardır: gcc baskılar olduğunuÖzel miras: ad arama hatası

#include <stdio.h> 

namespace my 
{ 
    class base1 
    { // line 6 
    }; 

    class base2: private base1 
    { 
    }; 

    class derived: private base2 
    { 
    public: 
     // The following function just wants to print a pointer, nothing else! 
     void print(base1* pointer) {printf("%p\n", pointer);} 
    }; 
} 

hatası: Şimdi

test.cpp:6: error: `class my::base1' is inaccessible

test.cpp:17: error: within this context

i ne sorunu tahmin edebilirsiniz : print bildirgesine bakıldığında, derleyici base1 görür ve düşünür: base1derived* this'un temel sınıf alt nesnesidir, ancak buna erişiminiz yoktur! Ben base1 sadece bir tür ismi olması gerektiğini düşünürken.

C++ Standardında bunun doğru bir davranış olduğunu ve derleyicide bir hata olmadığını nasıl görebilirim (eminim ki bir hata değil; tüm derleyicileri kontrol ettim)?

Bu hatayı nasıl düzeltmeliyim? Aşağıdaki tüm düzeltmeler çalışır, ancak hangisini seçmeliyim?

void print(class base1* pointer) {}

void print(::my:: base1* pointer) {}

class base1; void print(base1* pointer) {}


Düzenleme:

int main() 
{ 
    my::base1 object1; 
    my::derived object3; 
    object3.print(&object1); 
} 
+0

ana gönderebilir miyim()? –

+0

Özel mirasın, kompozisyonla aynı şey olmadığını gösteren güzel örnek! – curiousguy

cevap

12

aradığınız bölüm 11.1 olduğunu. Bu kullanarak :: benim :: Base1 * Bu sorunu gidermek için öneriyor:

[ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. — end note ]

[ Example: 
class A { }; 
class B : private A { }; 
class C : public B { 
A *p; 
// error: injected-class-name A is inaccessible 
:: A * q ; 
// OK 
}; 
+0

Enjekte edilen sınıf isminin ne olduğunu açıklayabilir misiniz? – davka

+1

Bölüm 9, nokta 2: Sınıf adı görüldükten hemen sonra bildirildiği kapsam içine bir sınıf adı eklenir. Sınıf adı da sınıfın kendi alanına eklenir; Bu, enjekte edilen sınıf adı olarak bilinir. Erişim denetimi amacıyla, enjekte edilen sınıf adı, bir genel üye adı gibi kabul edilir. Bir sınıf belirleyici genellikle bir sınıf tanımı olarak adlandırılır. Bir sınıf, üye işlevlerinin genel olarak henüz tanımlanmamış olmasına rağmen, sınıf belirleyicisinin kapanış ayracının görülmesinden sonra tanımlanmıştır. –

+1

Verilen cevaptan memnunsanız, @anatolyg, bunu başkalarının da görebilmesi için lütfen kabul edildi olarak işaretleyebilir misiniz? –