我有三个继承如下的类:
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_B
添加中间构造函数,因为Class_B
是生成的代码,每次我清理时都会重新生成。因此,我无法对Class_B
进行任何持久的更改。不用说,Class_C
中构造函数的上一行给出了error: "type 'Class_A' is not a direct base of '
Class_C '".
有没有办法可以调用子类Class_A
中Class_C
的构造函数,而不需要Class_B
中相同类型的构造函数?
答案 0 :(得分:4)
如果你无法更改生成B
的代码,那么你就不幸了,AFAIK。但是如果A
类包含这样的构造函数,也许你可以添加一个简单的成员函数来设置这两个变量并从C
构造函数中调用它?可能效率不高,但至少可行。
答案 1 :(得分:1)
如果可以使基类成为虚拟基类,则可以执行此操作,因为虚拟基础必须始终在最外层构造函数中未初始化。如果你无法改变ClassB从A继承的方式,你总是可以这样做:
RealClassA
ClassA : public virtual RealClassA
ClassB : public ClassA
ClassC : public ClassB
然后在ClassC构造函数中,您可以直接调用RealClassA(...)
。
通常虚拟遗产的特征是一个真正的痛苦,但它实际上可能对你有帮助。
答案 2 :(得分:1)
你可能已经塞满了(假设你不能改变B组的代),但是如果恰好有B的任何构造函数是模板,那么你可以专门化一个(对于一个唯一的虚拟类)并使用你想要的任何基类A构造创建自己的自定义构造函数....
否则,虽然效率较低,但显而易见,安全,干净的方法是使用A的operator=
(如果有的话)来获取您想要的值......
C c;
c = A(x, y);
如果A的那些区域只能在施工时设置,那么这是一个更难的问题......
(暂时深入到未定义行为的可怕领域,你可以调用A的析构函数然后放置new
它,但A的生命周期意味着跨越Bs和Cs。实际上,明显的风险是A创建类似于堆分配的值,B或C已经拥有指针,并且可能在析构函数释放后尝试使用....)
答案 3 :(得分:1)
唯一可能是Class_B
实际上从中继承
Class_A
;在这种情况下,将调用Class_A
的构造函数
来自最派生的类。但由于这也涉及到改变
代码生成器,或代码生成器的输入,你可能会
好吧改变它以将附加构造函数添加到Class_B
。
如果你真的无法以某种方式更改代码生成器或其输入
会导致它生成额外的构造函数,但你可以
更改Class_A
和Class_C
,然后有两种可能的解决方案:
Class_A
采用适当的参数,然后执行
构造函数完成后的初始化。虽然最简单,
只有在Class_A
可以支持默认值时才能使用此方法
如果Class_A
的所有成员都支持,那么也是如此
赋值,语义使得遵循默认构造
通过赋值与使用参数的构造具有相同的结果
你给(即没有参考成员,没有非成员,没有
const
成员等)。
Class_A
在一个单独的类中的数据成员,并且Class_A
虚拟地来自这个类。 Class_C
然后会调用。{
这个新类的构造函数。
答案 4 :(得分:0)
如果生成B,则更改生成器,否则您注定失败。
根据B的作用,可能是一种解决方案,可以将您的设计更改为直接从A和B进行C派生(如果A是您的容器类,B是处理类)。执行此操作可能需要您使用模板B.如果B需要对A成员执行操作,您仍然可以给出指向B构造函数的A指针...
答案 5 :(得分:0)
您可以为Class_B
添加一个构造函数,该构造函数与Class_A
的ctor具有相同的签名,然后让Class_C
在ctor中调用它。
此外,类ctor初始化列表无法为基类中的成员设置值(无论它们是private
protected
还是public
)。您必须使用基类'ctor来设置它们。
答案 6 :(得分:0)
按语言,不能访问非直接的基础构造函数。
顺便说一下,如果Class_A
构造函数签名是
Class_A(const char *name, int kind);
然后,Class_B
应该有一些构造函数,它将接受给定类型的Class_A
构造函数。否则会给编译器错误。
摆脱该错误的唯一方法是为Class_A::Class_A(...)
提供默认参数。