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

How to define inner class member in derived class?

本文关键字:定义 内部类 成员 派生      更新时间:2023-10-16
#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;
}
有没有办法在派生类中定义内部类成员?这个错误背后的原因是什么?

问题是,您试图在不同的类范围内定义函数,而不是在其中声明的函数。例如,考虑一下您的代码的扩展版本:

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的类型定义的使用是显式的,作为A::B而不是B。由于类型的不同,名称B在分别用作A::BC::B时将表示A::AB_C::CB_

// 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_