struct T
{
int a;
};
struct C
{
T& r;
C(T& v) : r(v) {}
};
struct E : T
{
T& r;
E(T const& v) : r(*this), T(v) {} // ok
};
struct F : C, T // base order doesn't matter here
{
//F(T const& v) : C(*this), T(v) {} // error : C::r is not initialized properly
F(T const& v) : C(*static_cast<T*>(this)), T(v) {} // ok
//F(T const& v) : C(static_cast<T&>(*this)), T(v) {} // ok
};
int main()
{
T v;
F f(v);
f.r.a = 1;
}
尽管在初始化列表中使用此指针可能会有问题,但我从未预料到这会发生在POD中,并且可能只是通过显式转换修复; 这是一些编译器错误还是与std相关的问题?
答案 0 :(得分:3)
当您尝试使用C
初始化F
的基础*this
时,编译器为C
生成了复制构造函数,并且您定义的构造函数为T&
1}}是匹配,因为*this
(F
)的类型直接来自C
和T
。你的演员阵容解决了这种模糊性。
我很惊讶复制构造函数比采用T&
的复制构造函数更好,因为我认为它们都是同样优先的。如果选择了复制构造函数,那么将从自身初始化base,这会导致未定义的行为,因为引用成员将从未初始化的引用(本身)初始化。
答案 1 :(得分:3)
代码含糊不清。
为了构造C
的{{1}}基,上下文是直接初始化,所以适用13.3.1.3:
13.3.1.3构造函数初始化[over.match.ctor]
对于直接初始化,候选人 函数是正在初始化的对象的类的所有构造函数。
包含隐式声明的复制构造函数,每12.8:8。
F
的构造函数的候选者是C
和(默认的复制构造函数)C(T &)
,参数列表C(const C &)
。在这两种情况下,我们都有一个参考绑定(13.3.3.1.4),然后是派生到基础的转换(13.3.3.1),在后一种情况下进行额外的cv资格调整,在两种情况下给出转换的总体排名
由于(F)
和C
都是T
的基类,但它们是不同类型,并且都不是另一个的基类,13.3.3.2中没有任何子句:3并且13.3.3.2:4适用并且转换序列无法区分。
实际上,gcc-4.5.1拒绝使用以下代码:
F
答案 2 :(得分:0)
struct C { T& r; C(T& v) : r(v) {} }; struct E : T { T& r; E(T const& v) : r(*this), T(v) {} // ok };
您需要在声明时初始化任何引用,但在此您刚刚声明了它。这在C ++中是不允许的。
答案 3 :(得分:0)
1)从不在初始化列表中使用它 http://msdn.microsoft.com/en-us/library/3c594ae3(v=vs.80).aspx this指针仅在非静态成员函数中有效。它不能在基类的初始化列表中使用。
在此构造函数之前调用基类构造函数和类成员构造函数。实际上,您已将指向未构造对象的指针传递给另一个构造函数。如果其他构造函数访问任何成员或调用成员函数,结果将是未定义的。在完成所有构造之前,不应使用this指针。
很快:C.r由糟糕的人物初始化