C++ 构造函数初始化与赋值 让我们考虑下面的类 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; } };

C++ 构造函数初始化与赋值 让我们考虑下面的类 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; } };,c++,constructor,C++,Constructor,现在,我知道test1()构造函数是初始化类的数据成员的正确方法,因为在test2()中,我们执行赋值而不是初始化。我的问题是: 如果我们执行赋值而不是初始化,会出现什么问题 编译器在test1()构造函数的情况下不在内部执行赋值吗?如果没有,那么这些是如何初始化的 对于您的示例,没有什么真正的区别,因为您正在初始化纯整数 但是假设这些整数是具有构造函数的对象,那么编译器将生成以下调用: // test1 a::copy_constructor(0); b::copy_constructor(0

现在,我知道
test1()构造函数
是初始化
的数据成员的正确方法,因为在
test2()
中,我们执行赋值而不是初始化。我的问题是:

  • 如果我们执行赋值而不是初始化,会出现什么问题
  • 编译器在
    test1()
    构造函数的情况下不在内部执行赋值吗?如果没有,那么这些是如何初始化的

  • 对于您的示例,没有什么真正的区别,因为您正在初始化纯整数

    但是假设这些整数是具有构造函数的对象,那么编译器将生成以下调用:

    // test1
    a::copy_constructor(0);
    b::copy_constructor(0);
    
    
    // test2
    a::default_constructor();
    b::default_constructor();
    a::operator = (0);
    b::operator = (0);
    
    因此,根据您的对象,test2可能会对性能产生巨大影响。另外,通过在初始化列表中初始化对象,可以确保在进入构造函数时变量具有数据。初始值设定项列表的一个“缺点”是,它是按照变量声明的顺序执行的,而不是按照初始值设定项列表的顺序执行的,因此可能是您不想使用初始值设定项列表

    如果我们执行赋值而不是初始化,会出现什么问题

    某些类类型(以及引用和
    const
    对象)无法分配;有些不能默认初始化;有些默认初始化和重新分配可能比直接初始化更昂贵

    对于test1()构造函数,编译器不是在内部执行赋值吗?如果没有,那么这些是如何初始化的

    对于像
    int
    这样的基元类型,两者之间几乎没有实际区别。默认初始化不起任何作用,而直接初始化和赋值基本上起着相同的作用

    在类类型的情况下,默认初始化、赋值和直接初始化都调用不同的用户定义函数,有些操作可能根本不存在;因此,一般来说,这两个例子可能有非常不同的行为。

    第三个变体。优点是

  • 变量不必在构造函数中进行默认初始化
  • 构造函数而不是复制/移动赋值运算符用于构造成员(正如其他答案所述,这与本例的原语类型无关)
  • 因此,这比问题中的两种变体都不容易出错:

    #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;
    }
    
    #包括
    类Test3
    {
    public://已公开,因此我们可以方便地输出变量。没有使用与问题一致的结构。
    int a{4};//构造函数中不需要单独初始化。
    int b{2};//构造函数中不需要单独初始化。
    };
    int main()
    {
    const auto t=std::move(Test3());//隐式声明的默认构造函数+隐式声明的移动赋值运算符
    看不到这个答案。。。