2011-06-27 35 views
7
class A { 
    public: 
     void fa() { 
     } 
    }; 

class B : public A{ 
public: 
    void fb() { 
    } 
}; 

class C : public A, public B { 
public: 
    void fc() { 
     //call A::fa(), not B::A::fa(); 
    } 
}; 
işlevinden A::fa()'u çağırma.

GCC, direct base A inaccessible in C due to ambiguity ile uyarır; bu, temel sınıf üyelerine başvurmanın doğrudan bir yolu olmadığı anlamına mı geliyor?Türetilmiş sınıf üyelerinden

+0

olduğu anlamına gelir. Eğer? – iammilind

+0

Hatam güncellenmiş kodu koymak mı :) , şimdi – MKo

+1

düzeltildi Bir "A" temel sınıf alt nesne, "C" veya iki "A" temel sınıf alt nesnesi olmasını istiyor musunuz? 'A')? Şu anda ikiniz var, niyetiniz olabilir ya da olmayabilir. –

cevap

0

Böyle problemi aşmak için virtual devralma kullanabilirsiniz:

class B : virtual public A { 

Şimdi, basitçe çocuğun class C içinde A::fa() kullanabilirsiniz. BA miras public müttefiki zaten olduğunda

void fc() 
{ 
    fa(); 
} 

Ancak, ben genellikle class C içine tekrar class A miras herhangi pratik gerek görmüyorum. Yani, senin durumda, basit yapabilirsiniz:

class C : public B { 

Düzenleme:

Eğer A için 2 örneklerini istiyorum. o zaman niyetinde direkt örneği C bir nesne olarak yapılabilir: haiz

class C : public B { 
    A obj; 

Çünkü bir doğrudan kalıtsal A yine kullanılabilecek olmayacaktır. C kapsamında herhangi bir işaretçi veya başvuru beyan edemezsiniz.

+0

Bu pratik kullanım için değil, sadece bilmek istediğim bir şey var mı? Bu arada sanal miras durumunda, bir A sınıfı olacak ve hiçbir belirsizlik olmayacak. – MKo

+0

@MKo, Düzenlenmiş cevabımda zaten belirtmiştim. Davanız için, A'yı "C" ye devretmeniz gerekmiyor. Ayrıca uzun vadede kötü bir tasarım olabilir. – iammilind

1

Ben sadece C::fc() işlevinden() A::fa() fa çağırmak için yeterlidir koyarak, codepad.org konusunda size kodunu derlenmiş.

void fc() { 
     A::fa(); 
    } 

Aşağıdaki kod kodunuzla bağlantıdır.

http://codepad.org/NMFTFRnt

+0

Derleyici kod defterinin ne kullandığını bilmiyorum, ancak 3.0/133044 ve g ++ 4.5.1 clangları bunu reddediyor. –

+0

@James McNellis: Evet, daha çok dil ile değil, ** derleyici sorunuyla ilgilidir. – Jhaliya

+0

Bu kod, "B" kodunuzda "A" türetmediğinden derleniyor. –

8

Bir seçenek doğru taban sınıfı altnesnesi için döküm için kullanabileceğiniz bir saplama sınıfı oluşturmak olacaktır:

struct A { 
    void fa() { } 
}; 

struct B : A { 
    void fb() { } 
}; 

// Use a stub class that we can cast through: 
struct A_ : A { }; 

struct C : A_, B { 
    void fc() { 
     implicit_cast<A_&>(*this).fa(); 
    } 
}; 

implicit_cast tanımlanır Nerede gibidir:

template <typename T> struct identity { typedef T type; } 

template <typename T> 
T implicit_cast(typename identity<T>::type& x) { return x; } 
+0

Kabul ediyorum, Bu soru ile boğulmuş ve kafes içine bir saplama sınıfı enjekte etmeden bunu yapmak için bir yol olup olmadığı konusunda çok ilgileniyorum. –

+0

Bir saplama kullanmak güzel bir çözümdür, böyle bir hile olmadan bu davranışı gerçekleştirmenin herhangi bir yolu olduğunu sanmıyorum. Bu hiç düşünmediğim dilin bir sınırlaması! –

+0

Neden "static_cast" yerine "implicit_cast" kullanıyorsunuz? Soruyu cevaplayan bir SO postu buluyorum, ancak belki de biraz açıklama veya bununla ilgili bazı bilgilere bağlantı ekleyebilirsiniz. –

0

Ne istersen yapabileceğini düşünmüyorum. Burada bir belirsizlik var: A::fa() derken, hala derleyiciye hangi A nesnesinin kullanılacağını söylemez. A sınıfına erişmenin herhangi bir yolu yoktur. Bu, uyarının size söylediği şey. Yine de bu çok garip bir yapıya benziyor. Kamu-miras ilişkileri bir ilişki için kullanılmalıdır. C'un iki kere üzerinde A olduğunu söylüyorsunuz? Mantıklı değil. Ve bu, bunun ya pratikte asla ortaya çıkmayacak bir yapay örnek olduğunu ya da bu tasarımı tekrar gözden geçirmeniz gerektiğini gösteriyor.

5

Aşağıdaki bilgileri sadece ISO C++ 2003 standardında buldum (10.1.3)

A class shall not be specified as a direct base class of a derived class more than once. [Note: a class can be 
an indirect base class more than once and can be a direct and an indirect base class. There are limited 
things that can be done with such a class. The non-static data members and member functions of the direct 
base class cannot be referred to in the scope of the derived class. However, the static members, enumerations 
and types can be unambiguously referred to. 

O `sınıf A` miras değil doğrudan bir yolu :(andaki kod` sınıf B` olarak

İlgili konular