在初始化列表中使用此指针

时间:2012-08-07 14:19:51

标签: c++

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相关的问题?

4 个答案:

答案 0 :(得分:3)

当您尝试使用C初始化F的基础*this时,编译器为C生成了复制构造函数,并且您定义的构造函数为T& 1}}是匹配,因为*thisF)的类型直接来自CT。你的演员阵容解决了这种模糊性。

我很惊讶复制构造函数比采用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由糟糕的人物初始化