首页 > 解决方案 > 在构造函数中初始化类成员变量

问题描述

我最近开始研究 C++,在通过初始化列表初始化成员变量时,我观察到一种奇怪的行为。

//Demo.h
#ifndef DEMO
#define DEMO
#include <iostream>
class Demo
{
public:
    Demo();
    explicit Demo(int x);
};

#endif 

//Demo.cpp
#include "Demo.h"
Demo::Demo()
{
    std::cout << "Demo()" << std::endl;
}
Demo::Demo(int x)
{
    std::cout << "Demo(int x)" << std::endl;
}

//Test.cpp
#include "Demo.h"
class Test
{
public:
    Test()
    // : d_(123)
    {
    }

private:
    Demo d_;
};
int main(int argc, char const *argv[])
{
    Test t;
    return 0;
}

在上面的代码片段中,我为 Demo( d_) 类创建了一个对象,当我运行程序时Demo()正在打印。但是,如果我取消注释已注释的代码(d_(123)),我将得到Demo(int x)输出。

第一种情况我很清楚,但第二种情况我无法理解? 编辑: 我的问题是我已经创建了一个对象(成员变量 In-class Test),但我再次在初始化列表中传递了整数参数。那么是否可以通过,因为对象已经创建并再次尝试初始化它?

标签: c++

解决方案


当您只是在类的主体中声明它时,您不会初始化数据成员实际上,当您为类编写定义时,您根本不会创建任何东西,它只是创建类的未来实例的蓝图。后来,当你创建一个类类型的对象时,对象是通过相应的构造函数创建的,然后我们才初始化数据成员。

定义类后,将其实例化为

Test t; // an object created, default constructor is used 

在这种情况下,t使用Test. 此默认构造函数使用的构造函数初始化类d_的类型数据成员,该构造函数采用.DemoDemoint

当您构造一个对象时,成员初始化器列表中的所有数据成员仍将被实例化 (它们不是默认构造的,它们仍需以某种方式构造)这就是成员初始化列表的美妙之处。

因此,一个对象可以是默认构造的,但它可以使用其他构造函数(非默认)构造,在这种情况下,甚至不会触及默认构造函数。

请注意,如果您要避免在构造函数的主体中使用成员初始化器列表和初始化的数据成员,则数据成员将首先被默认构造,然后重新分配新值(在构造函数的主体中)


推荐阅读