Refer base class members from derived class

喜夏-厌秋 提交于 2019-12-08 18:59:07

问题


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

How to call A::fa() from C::fc() function.

GCC warns withdirect base A inaccessible in C due to ambiguity, does this mean there is no direct way to refer base class members?


回答1:


One option would be to create a stub class that you can use for casting to the right base class subobject:

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

Where implicit_cast is defined as:

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

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



回答2:


I just found the following info from ISO C++ 2003 standard (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.

It means there is no direct way :(




回答3:


I just compiled you code on codepad.org , putting A::fa() is enough to call fa() from your C::fc() function.

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

The below is the link to codepad with your code.

http://codepad.org/NMFTFRnt




回答4:


I don't think you can do what you want. There is an ambiguity here: when you say A::fa(), it still doesn't tell the compiler which A object to use. There isn't any way to access class A. That's what the warning is telling you.

This seems like an awfully strange construct, though. Public inheritance should be used for is-a relationships. You are saying that C is-a A twice over? It doesn't make sense. And that suggests that this is either an artificial example that would never come up in practice, or you should reconsider this design.




回答5:


You can use virtual inheritance to overcome such problem:

class B : virtual public A {

Now, you can use A::fa() simply in the child class C.

void fc()
{
  fa();
}

However, I generally don't see any practical need to inherit class A again into class C, when B is already publically inheriting A. So, In your case, you can make it simple:

class C : public B {

Edit:

If you want 2 instances for A. then the direct instance which you are intending can be made as an object of C:

class C : public B {
  A obj;

Because, having a directly inherited A will not be usable in anyway. You cannot declare any pointer or reference to it inside the scope of C.



来源:https://stackoverflow.com/questions/6488772/refer-base-class-members-from-derived-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!