嵌套构造函数对类成员的C ++初始化

时间:2012-01-06 14:46:13

标签: c++ initialization

是否可以初始化这样的类?

Quaternion::Quaternion(){ //default without arguments
    Quaternion(0.,V3(0.,0.,0.));
}


Quaternion::Quaternion(double s, V3 v){ //with scalar and vector as a argument
    coords[0] = s;
    coords[1] = v[0];
    coords[2] = v[1];
    coords[3] = v[2];
}

因为这是输出:

QUATERNION TEST
(2.122e-313:-3.22469e-232:2.122e-313:-1.998) //instanciated with Quaternion q;
(4:1:2:3) // instanciated with the Quaternion q(4,1,2,3);
(4:-1:-2:-3) // conjugated of the one above

并且第一个未初始化为0.因为它应该是......为什么?

5 个答案:

答案 0 :(得分:13)

不在C ++ 03中,但最新版本的C ++允许委派构造函数:

Quaternion() : Quaternion(0.0, V3(0.0,0.0,0.0)) { }

在委托构造函数中,初始化列表必须只有一个元素,这是另一个构造函数(显然不能有任何循环引用)。

如果你想在构造函数中直接初始化你的类成员,那么你不会真正解决复制/粘贴问题。也许您想使用默认参数?有些人反对那些......

explicit Quaternion(double s = 0.0, V3 v = V3(0.0,0.0,0.0)) { /* ... */ }

答案 1 :(得分:4)

Quaternion(0.,V3(0.,0.,0.));

这不会调用其他构造函数;相反,它会创建一个本地临时,在构造函数返回时会被丢弃。

在C ++ 03中,您唯一的选择是初始化两个构造函数中的所有成员,或者将初始化移动到两个构造函数调用的单独函数中。

在C ++ 11中,您可以使用稍微不同的语法委托给不同的构造函数:

Quaternion::Quaternion() :
    Quaternion(0.,V3(0.,0.,0.))
{}

答案 2 :(得分:2)

这是一个名为委托构造函数的功能,实际上是在C ++ 11中引入的,之前没有。请注意,实际语法看起来不同:

Quaternion::Quaternion() //default without arguments
  : Quaternion(0.,V3(0.,0.,0.)) // delegating constructor
{
}


Quaternion::Quaternion(double s, V3 v) //with scalar and vector as a argument
  : coords{ s, v[0], v[1], v[2] } // better version if you're using C++11 anyways
{
}

您的代码所做的是它创建了一个临时的Quaternion对象,该对象立即被破坏。

答案 3 :(得分:1)

您正在Quaternion::Quaternion()中创建临时实例。如果您不想创建每个构造函数,请定义初始化成员函数,例如init(),或者等到在编译器中实现C ++ 11中的委托构造函数。

答案 4 :(得分:1)

默认构造函数只使用两个参数调用构造函数。然后将生成的Object放入堆栈,并在它离开构造函数时解构它。

因此,在Quaternion的构造时间内只有0个初始化的Quaternion没有参数,但它不是由默认构造函数构造的Quaternion。

您可以做的是,为参数设置标准值:

#include <cstdio>

class TestCl {
public:
  TestCl(int i = 0) {
    printf("%d\n", i); 
  };
};

int main(int argc, char** argv) {
  TestCl f(1);
  TestCl s;
  return 0;
}