从派生类中引用基类成员

时间:2011-06-27 05:04:08

标签: c++ multiple-inheritance

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();
    }
};

如何从A::fa()功能调用C::fc()

GCC警告direct base A inaccessible in C due to ambiguity,这是否意味着没有直接的方式来引用基类成员?

5 个答案:

答案 0 :(得分:8)

一个选项是创建一个可用于转换到右基类子对象的存根类:

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定义为:

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

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

答案 1 :(得分:5)

我刚刚从ISO C ++ 2003标准(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.

这意味着没有直接的方式:(

答案 2 :(得分:1)

我刚刚在 codepad.org 上编译了代码,将A::fa()放到C::fc()函数中调用fa()即可。

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

以下是您的代码与键盘的链接。

http://codepad.org/NMFTFRnt

答案 3 :(得分:0)

您可以使用virtual继承来克服此类问题:

class B : virtual public A {

现在,您只需在孩子A::fa()中使用class C

void fc()
{
  fa();
}

但是,当class A已经class C已经继承B时,我通常认为没有任何实际需要将public再次继承到A。所以,在你的情况下,你可以简化:

class C : public B {

修改

如果您想要A的2个实例。那么你想要的直接实例可以作为C的对象:

class C : public B {
  A obj;

因为,直接继承A无论如何都无法使用。您不能在C范围内声明任何指针或引用。

答案 4 :(得分:0)

我认为你不能做你想做的事。这里有一个含糊不清的地方:当你说A::fa()时,它仍然没有告诉编译器使用哪个A对象。没有办法访问班级A。这就是警告告诉你的。

但这似乎是一个非常奇怪的结构。公共继承应该用于is-a关系。您是说CA两次?这没有意义。这表明这是一个在实践中永远不会出现的人为例子,或者你应该重新考虑这个设计。