如何在派生类中定义内部类成员?

时间:2016-06-29 21:24:10

标签: c++

#include<iostream>
using namespace std;
class A{
    public:
        class B{
            public:
                void fun1();
        };
};

class C:public A{
    public:
        B::fun1(){ // This line gives Error:can not define member function B::fun1() in C

        }       
};
int main(){
    C ob;
    return 0;
}

有什么方法可以在派生类中定义内部类成员? 这个错误背后的原因是什么?

1 个答案:

答案 0 :(得分:2)

问题在于您尝试在不同于其声明的类范围内定义函数。例如,请考虑代码的扩展版本:

class A{
    public:
        class B{
            public:
                void fun1();
                void fun2();
        };

        void fun3();

        void B::fun2() {} // Error.
};

class C:public A{
    public:
        void B::fun1() {} // Error.
        void A::fun3() {} // Error.
};

所有三个错误都会提供相同类型的错误消息“Can not define member function X::Y() in Z”。

要解决此问题,如果A::B::fun1()C::B::fun1()需要具有不同的实现,您也可以从嵌套类派生。

class A {
  public:
    class AB_ {
      public:
        virtual void fun1();
    };

    typedef AB_ B;
};
void A::AB_::fun1() {}

class C : public A {
  public:
    class CB_ : public A::AB_ {
        void fun1() override;
    };

    typedef CB_ B;
};
void C::CB_::fun1() {}

在这种情况下,您可以在外部使用B来访问嵌套类的派生程度最高的版本,或直接使用A::AB_C::CB_。同样,你可以这样写:

class A {
    class AB_ {
      public:
        virtual void fun1();
    } b;

  public:
    typedef AB_ B;

    virtual B& getB() { return b; }
};
void A::AB_::fun1() {}

class C : public A {
    // Note the use of the typedef, instead of the actual type name.
    class CB_ : public A::B {
        void fun1() override;
    } cb;

  public:
    typedef CB_ B;

    // Note the use of the typedef, instead of the actual type name.
    A::B& getB() override { return cb; }
};
void C::CB_::fun1() {}

在这种情况下,C在内部使用A的typedef,同时替换它;因此,使用A的typedef是明确的,A::B代替B。由于typedef,名称B分别表示A::AB_C::CB_,分别用作A::BC::B

// If given the above...

int main() {
    std::cout << "A::B: " << typeid(A::B).name() << std::endl;
    std::cout << "C::B: " << typeid(C::B).name() << std::endl;
}

输出将是:

// GCC:
A::B: N1A3AB_E
C::B: N1C3CB_E

// MSVC:
A::B: class A::AB_
C::B: class C::CB_