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的复制构造函数的问题鲁克托,但我想我已经用你的建议解决了这个问题。我只是希望