在 C++0x 中继承构造函数
Posted
技术标签:
【中文标题】在 C++0x 中继承构造函数【英文标题】:Inheriting constructors in C++0x 【发布时间】:2011-03-23 10:07:36 【问题描述】:假设我在我们期望成为下一个 C++ 标准的代码中有以下代码:
int f(int x)
std::cout << x;
return x * x;
struct A
A(int x) : m_x(x)
int m_x;
;
struct B : A
using A::A;
B() : m_y(f(m_x))
int m_y;
;
int main()
B(5);
这会调用 B 的默认构造函数并打印出 5 并设置 m_y = 25 吗?还是 B 的默认构造函数不会运行,而 m_y 未初始化?
如果是后者,不调用 B 默认构造函数的原因是什么?很明显,A(int) B 仅继承初始化 A,并使 B 处于不确定状态。为什么 C++ 会选择未定义的行为而不是简单地调用 B() 的默认构造函数?它在很大程度上违背了继承构造函数的目的。
编辑:
也许这应该被允许:
using A::A : m_y(...) std::cout << "constructing..." << std::endl; ...;
【问题讨论】:
m_y 将未初始化,通过使用 A::A,您将得到如下内容:B::B(int x) : A::m_x(x) 。或者什么:) C++ 实际上选择编译带有错误的代码,因为您没有为 A 提供默认构造函数。它不是未定义的行为 :) 【参考方案1】:using A::A;
在派生类中隐式声明B(int)
。就是这样。
程序的其余部分不应按预期工作。因为您使用B(5)
调用B(int)
,所以m_y
未初始化。
请参阅 Bjarne Stroustrup 网站上的此示例:
struct B1
B1(int)
;
struct D1 : B1
using B1::B1; // implicitly declares D1(int)
int x;
;
void test()
D1 d(6); // Oops: d.x is not initialized
D1 e; // error: D1 has no default constructor
http://www2.research.att.com/~bs/C++0xFAQ.html#inheriting
来自同一链接的另一个示例:
struct D1 : B1
using B1::B1; // implicitly declares D1(int)
int x0; // note: x is initialized
;
void test()
D1 d(6); // d.x is zero
【讨论】:
如果 D1 有一个默认构造函数,它会在运行“D1 d(6);”行时运行吗? 他的示例没有为 D1 声明默认构造函数。当然,无论“使用 B1:B1”如何,x 都不会被初始化。然而,我的示例声明了一个默认构造函数。 @Clinton:是的。但是在您的示例中未调用默认构造函数。所以不管你是否定义它,你调用隐式声明的构造函数,在你的例子中是B(int)
。
@Nawaz:为什么?不调用默认构造函数的原因是什么?在 C++ 中的任何其他实例中,您都不能在不调用其构造函数的情况下创建对象。
+1 @Clinton:如果您考虑一下using B1::B1
对编译器的含义,可能会更容易理解。该构造被翻译(在这种特殊情况下)为D1( int __x ) : B1(__x)
。请注意,这并不意味着调用B1 构造函数,而是创建一个将调用B1 构造函数的D1 构造函数。该构造函数没有显式修改成员x
,因为它是int
类型,这意味着它未初始化。除非按照最后的代码 sn-p,它使用声明中的初始化语法,在这种情况下它将被正确初始化。以上是关于在 C++0x 中继承构造函数的主要内容,如果未能解决你的问题,请参考以下文章