c++初始化列表

C++ initialization list

本文关键字:列表 初始化 c++      更新时间:2023-10-16

下面是我不完全理解的关于初始化列表的代码。特别是这一页的最后一块(red(Bow("red")) and blue(Bow("blue"))。

Bow是.h文件中包含的另一个类,其构造函数的形式为Bow(string aColor)

初始化语法为
ClassName(argumentlist): datamember1(value1), dataMember2(value2){}

我不明白这个初始化是如何工作的。我理解在类ArcheryCompetition中制作类Bow的对象,这几乎就像在另一个构造函数的初始化列表中调用另一个类的构造函数一样。这是我正在读的一本初学者的书。

如果需要进一步说明,请告诉我。

class ArcheryCompetition
{
//member variables
private:
    //variables
    int rounds;
    float redScore;
    Bow red;
    float blueScore;
    Bow blue;
public:
    //constructor
    ArcheryCompetition( int lrounds);
    //destructor
    ~ArcheryCompetition();
    //methods
    int compete(void);
};
ArcheryCompetition::ArcheryCompetition(int lrounds):
rounds(lrounds), red(Bow("red")), blue(Bow("blue")), redScore(0), blueScore(0)**
{
}

由于成员redblue都是Bow类的实例,因此调用red("red")blue("blue")就足够了。它将使用选定的参数调用类Bow的构造函数:

ArcheryCompetition::ArcheryCompetition(int lrounds):
rounds(lrounds), red("red"), blue("blue"), redScore(0), blueScore(0)
{
}

红(弓("红")) 实际上是调用拷贝构造函数

Bow(const Bow& toCopy); 

创建Bow的临时实例,带"red"参数调用其构造函数,并将该临时对象逐字节复制到为red成员保留的内存中。我知道这可能有点令人困惑,我不知道为什么这样的结构被放在书中,而没有解释什么是复制构造函数。

你可以在这里找到一些很好的解释:http://www.cplusplus.com/articles/y8hv0pDG/

例如

Bow("red")

正在调用Bow构造函数

初始化项

red(Bow("red"))

用参数"red"调用Bow构造函数,然后用新的(匿名的)Bow初始化red

Bow("red")将为您提供一个Bow类的实例。

red(Bow("red"))表示用Bow("red")初始化日期成员red

代码

 ArcheryCompetition::ArcheryCompetition(int lrounds)
    : rounds(lrounds), red(Bow("red")), blue(Bow("blue")), 
      redScore(0), blueScore(0)
 {
 }

ArcheryCompetition定义了一个构造函数,它将成员变量rounds设置为lround,用"red"调用Bow构造函数,并设置red成员变量(为副本,因此使用复制构造函数),等等。

和你的术语有点混乱:c++ 11标准给你的初始化列表是完全不同的…

演示下面的操作。

Bow("red");
Bow red("red");
Bow red = Bow("red");
Bow redbow("red"); Bow red(redbow);

如果你得到这些,但仍在努力

red(Bow("red"))

,那么这将是一个学习不要给成员变量起模棱两可的名字的好时机,这样就不能将它们与局部变量区分开,例如

class ArcheryCompetition
{
...
    int m_rounds;
    Bow m_red;
    Bow m_blue;
...
    ArcheryCompetition(int rounds_) // distinguish parameters from local variables too
        : m_rounds(rounds_)
        , m_red(Bow("red"))
        , m_blue(Bow("blue"))
        ...
    {}
...
};

在构造函数声明之后,":"语法表示一个"初始化列表",用于初始化类的成员——其中初始化意味着构造。它基本上是在说"当我被构造时,这就是我的成员应该如何被构造"——所以你说的其他类的构造函数被调用是完全正确的;它们将根据您的规范在您的类成员上被就地调用。因此,"m_blue(Bow("Blue")))"告诉编译器在调用该构造函数时使用参数"Blue"来初始化m_blue成员。

除了在这种情况下,通过添加类名,您实际做的是

Bow redbow("red");
m_red(redbow);

创建一个临时的Bow对象,初始化为值"red",然后使用Bow的复制构造函数将数据复制到m_red中。

你实际上可以简化(改进)构造函数到

    ArcheryCompetition(int rounds_) // distinguish parameters from local variables too
        : m_rounds(rounds_)
        , m_red("red")
        , m_blue("blue")
        ...
    {}
编辑:

看到

class MyClass {
    int i;
     YourClass m_yourClass1, m_yourClass2;
public:
    MyClass()
      : m_i(10)
      , m_yourClass1( YourClass(1) )
      , m_yourClass2( 2 )
    {}
};
void foo() {
     MyClass myClass;
     ...
}

然后,粗略地说,"foo"的第一行会导致类似这样的事情发生:

MyClass* myClassPtr = make_room_on_stack_for(sizeof(MyClass));
// : m_i(10)
myClassPtr->m_i = 10;
// , m_yourClass1( YourClass(1) )
YourClass* temporary = make_room_on_stack_for(sizeof(YourClass));
temporary->YourClass(1);
if(YourClass has a copy constructor (YourClass::YourClass(const YourClass&))
    myClassPtr->m_yourClass1->YourClass(temporary); // copy constructor
else
    myClassPtr->m_yourClass1->operator=(temporary); // assignment operator
delete temporary;
// , m_yourClass2( 2 )
myClassPtr->m_yourClass2->YourClass(2);