通过嵌套构造函数对类成员进行C++初始化

C++ initialization of class members by nested constructors

本文关键字:C++ 初始化 成员 嵌套 构造函数      更新时间:2023-10-16

有可能初始化这样的类吗?

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。应该是…为什么?

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

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

在委托构造函数中,初始值设定项列表必须恰好有一个元素,即另一个构造函数(显然不能有任何循环引用)。

如果您想直接在构造函数中初始化类成员,那么在C++11之前,您就无法真正绕过复制/粘贴。不过,也许您想使用默认参数?有些人反对这些。。。。

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

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

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

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

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

这是一个名为委派构造函数的功能,实际上是在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对象。

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

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

因此,初始化为0的四元数只在没有参数的四元数来构造时存在,但它不是由默认构造函数构造的四元量。

您可以做的是,对参数的标准值进行asssign:

#include <cstdio>
class TestCl {
public:
  TestCl(int i = 0) {
    printf("%dn", i); 
  };
};
int main(int argc, char** argv) {
  TestCl f(1);
  TestCl s;
  return 0;
}