Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中,是否可以调用一个超类的构造函数,该超类与当前类相隔两个类+;_C++_Inheritance_Constructor - Fatal编程技术网

C++ 在C+中,是否可以调用一个超类的构造函数,该超类与当前类相隔两个类+;

C++ 在C+中,是否可以调用一个超类的构造函数,该超类与当前类相隔两个类+;,c++,inheritance,constructor,C++,Inheritance,Constructor,我有三个类继承如下: Class_A Class_B : public Class_A Class_C : public Class_B Class_A包含一个构造函数: public: Class_A(const char *name, int kind); Class_B不包含该构造函数 在Class_C中,我希望调用Class_A的构造函数。类似: Class_C(const char*name,int kind):Class_A::Class_A(name,kind){} 问

我有三个类继承如下:

Class_A  
Class_B : public Class_A  
Class_C : public Class_B
Class_A
包含一个构造函数:

public: Class_A(const char *name, int kind);
Class_B
不包含该构造函数

Class_C
中,我希望调用Class_A的构造函数。类似:
Class_C(const char*name,int kind):Class_A::Class_A(name,kind){
}

问题是,我无法向
类B
添加中间构造函数,因为
类B
是生成的代码,每次我清除时都会重新生成。因此,我无法对
Class_B
进行任何持久的更改。不用说,
Class_C
中构造函数的上面一行给出了
错误:“type'Class_A'不是'
Class_C
'的直接基。”


有没有一种方法可以让我调用子类
Class\u C
中的
Class\u a
的构造函数,而不需要
Class\u B
中相同类型的构造函数?

如果你不能更改生成
B
的代码,那你就倒霉了,阿飞。但是如果
A
类包含这样一个构造函数,那么您可以添加一个简单的成员函数来设置这两个变量,然后从
C
构造函数内部调用它?可能没有它得到的那么有效,但至少它能工作。

如果生成了B,那么就更换生成器,否则你就注定要失败


根据B所做的工作,可能有一种解决方案可以将设计更改为直接从a和B派生C(如果a是容器类,B是处理类)。这样做,可能需要你模板B。如果B需要作用于A成员,你仍然可以给B构造函数一个指针…

你可以为
类B
添加一个构造函数,它与
类A
的ctor具有相同的签名,然后让
类C
在ctor中调用它


此外,类ctor初始化列表无法为基类中的成员设置值(无论它们是
私有的
受保护的
还是
公共的
)。必须使用基类的构造函数来设置它们。

按语言,不能访问非直接基类构造函数

顺便说一下,如果构造函数签名是

Class_A(const char *name, int kind);
然后,
Class_B
应该有一些构造函数,这些构造函数将容纳给定类型的
Class_A
构造函数。否则将导致编译器错误


消除该错误的唯一方法是为
Class_A::Class_A(…)

提供默认参数,如果可以将基类设置为虚拟基类,则可以这样做,因为虚拟基类必须始终在最外层的构造函数中直接取消初始化。如果无法更改ClassB从A继承的方式,则始终可以执行以下操作:

RealClassA
ClassA : public virtual RealClassA
ClassB : public ClassA
ClassC : public ClassB
然后在ClassC构造函数中,您可以直接调用
RealClassA(…)

通常,虚拟继承的这一特性是一个真正的难题,但它实际上可能会对您有所帮助。

您可能已经吃饱了(假设您无法更改类B的生成),但是如果碰巧有任何B的构造函数是模板,那么您可以专门指定一个(用于唯一的虚拟类)并创建您自己的自定义构造函数,使用您喜欢的任何基类-A构造

否则,虽然效率较低,但显而易见的、安全的、干净的方法是使用A的
操作符=
(如果有的话)来获取您想要的值

C c;
c = A(x, y);
如果A的这些字段只能在构建时设置,那么这是一个更难的问题


(暂时深入到未知行为的可怕领域,你可以调用A的析构函数,然后放置
new
它,但A的寿命意味着跨越Bs和Cs。实际上,明显的风险是A创建了一个类似堆分配值的东西,B或C已经持有指向它的指针,并可能在dest之后尝试使用它构造函数释放它……)

唯一的可能性是
类B
Class_A
;在这种情况下,将调用
Class_A
的构造函数 从最派生的类。但由于这也会涉及更改 代码生成器或代码生成器的输入,您可以 我们将其更改为将附加构造函数添加到
类B

如果您真的无法以以下方式更改代码生成器或其输入: 将导致它生成额外的构造函数,但您可以 更改
A类
C类
,则有两种可能的解决方案:

  • 最简单的方法就是使用延迟初始化;向
    Class_A
    ,它采用适当的参数,并执行 构造函数完成后初始化。虽然最简单, 只有当
    Class_A
    可以设置为支持默认值时,才能使用此方法 如果
    A类的所有成员都支持
    赋值,语义上遵循默认的构造
    by赋值与使用参数的构造具有相同的结果
    您提供(即,没有参考成员,没有非可视成员,没有
    
    const
    成员等)。
  • 或者,您可以将所有功能(或至少
    Class\u A
    的数据成员),并具有
    Class\u A
    几乎从这个类派生。
    class_C
    将调用 这个新类的构造函数。
  • 您不能更改生成B?Ew的所有
    类前缀的代码吗?@Xeo,在问题OP中提到:
    类B
    不包含该构造函数。好主意!我已经按照您的建议实现了类C的构造函数,它工作得很好。我还遇到了一些需要名称const的复制构造函数的问题鲁克托,但我想我已经用你的建议解决了这个问题。我只是希望