构造函数初始化Vs赋值
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++尝试使用类初始化成员对象默认构造函数。如果不存在默认构造函数,则为无法初始化对象
相关文章:
- 为"adjacent"变量赋值时出现问题
- C++中的赋值发生,尽管右侧出现异常
- 用C++中的sscanf赋值
- 为std::string的某个索引赋值
- 重载Singly Linked List中的赋值运算符
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- gtest_使用setargpointee在函数中赋值
- 非常量变量只读位置的赋值
- 使用赋值运算符重载从类中返回jobject
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 可以错误地使用赋值运算符而不是比较运算符的地方,= Vs ==
- C++空映射赋值:等于vs插入
- 绕过自动生成的赋值运算符(VS 错误?
- 'for' 循环中的 'int i = 0' vs. 'int i(0)'(赋值与初始化计数变量)
- Linux vs Windows std::map 赋值构造函数(为什么会有这样的区别?)
- 编译-vs运行时常量变量赋值和C++中vlas的分配
- 构造函数初始化Vs赋值
- VS 2015更新3删除拷贝赋值操作符错误
- 成员初始化列表vs赋值/复制构造函数(在boost deadline_timer中)
- 显式赋值vs隐式赋值