C++ 嵌套类继承自嵌套类

C++ 嵌套类继承自嵌套类,c++,inheritance,C++,Inheritance,我希望类C从类A继承它的虚拟函数,类D(类C中的嵌套类)从类B(类A中的嵌套类)继承它的数据字段,这是我所拥有的 文件1.h class A{ public: virtual void foo()=0; class B{ public: int data; }; }; 文件2.h class C : public A{ public: class D : public A::B{ }; }; fi

我希望类C从类A继承它的虚拟函数,类D(类C中的嵌套类)从类B(类A中的嵌套类)继承它的数据字段,这是我所拥有的

文件1.h

class A{
 public:
     virtual void foo()=0;
     class B{
       public:
         int data;
     };
};
文件2.h

class C : public A{
 public:
     class D : public A::B{

     };    
};
file2.cpp

void C::foo(){//code}
C::D::D():data(0){//Bad initialization list, error being data is not a member of C::D even it should inherits from its base class
 data = 0; //good! compiler can see data is a member of A::B,and C::D inherits from it
}
我有两个问题,第一个是,这就是我所做的,以正确的方式实现这种继承。其次,正如我所评论的,为什么编译器可以在手动初始化过程中看到来自A::B的数据,而不在初始化列表中?它们不应该在同一范围内吗?多谢各位

Edit1

因此,如果类C::D(foo)不是直接从A::B(foo)继承的,而是C从A继承的,那么我的感觉是,由于C继承了A及其所有公共字段,包括其内部类A::B(foo),D(foo)与A::B(foo)的名称完全相同,并且是C的内部类,就像这样,即对两个内部类都使用foo

class A{
 public:
     class foo{
       public:
         int data;
     };
};

class C : public A{
 public:
     class foo{

     };    
};
当我直接调用C::foo时,编译器会感到困惑吗?因为有两个构造函数的名称在作用域中?或者它选择调用“最近的”一个,例如C:foo?而不是爬上继承链?非常感谢

从句法角度看,这是正确的(*1)。当然,除了初始化列表之外。只能在初始值设定项列表中初始化当前类成员(不是基类成员)。这与筑巢无关

class X
{
public: 
   int x;
};
class Y : X
{
   Y() : x(0) {} //still illegal
};

我说句法视角是因为这是一件奇怪的事。。。我相信有一种更简洁的方法可以实现您真正想要的功能。

您从嵌套类继承的语法是正确的

初始化列表用于初始化该类的成员;基类成员应该在基类构造函数中初始化

  • 是的,您的方法是实现这种继承的正确方法

  • 初始值设定项列表用于控制传递给构造函数的参数。您可以将参数传递给B的构造函数,但不能直接初始化B的成员(这是其构造函数的工作)。如果没有为基类或成员指定构造函数,则使用默认构造函数。 在您的情况下,为B添加一个构造函数以实现您想要的

    class A {
    public:
        class B{
        public:
            B(int i) : data(i) {}
            int data;
        };
    }; 
    
    class C : public A {
        class D : public A::B {
        };
    };
    
    C::D::D() :B(0) { }
    

  • 从语法上来说,被接受的答案很好地回答了你的问题。 这是我关于机械装置设计方面的两分钱: 在您的示例中,抽象类A本质上是一个接口。接口应定义行为和仅定义行为。尽管如此,我认为在接口中使用嵌套类是没有意义的

    1) 接口没有任何要由嵌套类操作的数据成员,示例就是这样。这首先消除了嵌套类的需要

    2) 嵌套类不是一种行为。所以它不应该出现在界面中

    现在,您可能会争辩说,您的示例只是一个快速演示,实际上,您将有嵌套的数据成员可供操作,即类a不是纯接口。您只需要为嵌套类B提供一个默认实现,并让类C决定如何将类B自定义为自己的类D。如果是这种情况,恐怕设计会更糟

    3)考虑迭代器模式。类A本质上是一个无法实例化的抽象容器(因为其中有一个纯虚拟函数)——让我们将其映射到我们心目中的IContainer。现在创建一个C类,它有一个向量/数组实现,它自己的迭代器D指向数组中的某个元素

    然后,您需要创建另一个类E,它有一个哈希映射实现,使用她自己的迭代器F指针指向哈希映射中的某对

    这是一个灾难:在包含类(C,E…)的实现中,通常无法在所有迭代器类(D,F…)之间拥有统一的接口-很可能(考虑赋值运算符:
    BIterator operator=(const BIterator&other);
    ),类D有一个函数,它接受类D对象作为参数:
    DIterator操作符=(const-DIterator&other)
    ;类F有一些函数接受类F对象作为参数:
    FIterator操作符=(const FIterator&other)

    另一方面,这是行不通的,因为dieter和FIterator都是BIterator的子类-不能用“更窄”(或“更具体”)的参数重写函数,因为它违反了参数类型的相反性(C++不允许逆变参数,因此它需要匹配的参数类型;因此从技术上讲,您可以使用
    FIterator操作符=(const BIterator&other)
    对于类F,执行从BIterator到FIterator的运行时动态转换-但这很难看,也没有意义:一个具体的苹果有一个赋值操作符,它为自己分配一个抽象的“水果”。你只是让自己陷入了两难境地


    总而言之,由于1)2)和3)的原因,不要在接口/抽象基类中包含嵌套类。迭代器模式只是一个例子,在很多情况下,只要嵌套类与包含类交互,你就可能自食其果。如果没有,那么首先就没有必要使用嵌套类。

    在您的示例中,您的意思是Y应该从X继承吗?请为编辑提出另一个问题,而不是编辑旧问题。首先,公认的答案只适用于第一部分。你可以在新问题中引用这个问题。