[英]Constructor initialization Vs assignment
让我们考虑以下类
class test1
{
private:
int a;
int b;
public:
test1():a(0),b(0){}
};
class test2
{
private:
int a;
int b;
public:
test2()
{
a=0;
b=0;
}
};
现在,我知道test1()
构造函数初始化的数据成员的正确方法class
,因为在test2()
我们正在执行任务,而不是初始化。 我的问题是:
test1()
构造函数的情况下,编译器不会在内部执行赋值吗? 如果没有,那么这些是如何初始化的?如果我们执行赋值而不是初始化会出现什么问题?
某些类类型(以及引用和const
对象)无法分配; 有些不能默认初始化; 默认初始化和重新分配可能比直接初始化更昂贵。
在test1()构造函数的情况下,编译器是否在内部执行赋值? 如果没有,那么这些是如何初始化的?
在像int
这样的原始类型的情况下,两者之间几乎没有实际差别。 默认初始化什么都不做,直接初始化和赋值都基本上做同样的事情。
在类类型的情况下,默认初始化,分配和直接初始化每个调用不同的用户定义的函数,并且一些操作可能根本不存在; 所以一般来说,这两个例子可能会有非常不同的行为。
对于您的示例,没有真正的不同,因为您正在初始化普通整数。
但假设这些整数是带有构造函数的对象,那么编译器将生成以下调用:
// test1
a::copy_constructor(0);
b::copy_constructor(0);
// test2
a::default_constructor();
b::default_constructor();
a::operator = (0);
b::operator = (0);
因此,根据您的对象,test2可能会对性能产生巨大影响。 此外,通过在初始化列表中初始化对象,保证在输入构造函数时变量具有数据。 初始化列表的一个“缺点”是它按照声明变量的顺序执行,而不是按初始化列表的顺序执行,因此可能是您不想使用初始化列表。
利用直接列表初始化的第三种变体。 优点是
因此,这比问题中的两个变体都更不容易出错:
#include <iostream>
class Test3
{
public: // Made public so we can easily output the vars. No struct is used to be consistent with question.
int a { 4 }; // No need for separate initialization in constructor.
int b { 2 }; // No need for separate initialization in constructor.
};
int main()
{
const auto t = std::move(Test3()); // Implicitly-declared default constructor + implicitly-declared move assignment operator
std::cout << t.a << t.b;
}
输出是42
。
构造函数初始化器允许在创建数据成员时对其进行初始化。
一些程序员更喜欢在构造函数体中分配初始值。 但是,必须在构造函数初始化器中初始化几种数据类型。 以下几行总结了它们:
在创建后,您不能合法地为 const 变量赋值。 任何值都必须在创建时提供。
不引用某物,引用就不能存在。
C++ 尝试使用默认构造函数初始化成员对象。 如果不存在默认构造函数,则无法初始化对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.