0

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

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

初始化语法是

ClassName(argumentlist): datamember1(value1), dataMember2(value2){}

我不明白这个初始化是如何工作的。我理解在类Bow中创建一个类的对象ArcheryCompetition,就好像另一个类的构造函数在另一个构造函数的初始化列表中被调用。这一切都来自我正在阅读的一本初学者书籍。

如果需要更多说明,请告诉我。

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)**
{
}
4

6 回答 6

3

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

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

red(Bow("red"))实际上是对Bow的复制构造函数的调用。

Bow(const Bow& toCopy); 

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

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

于 2013-06-18T06:31:38.263 回答
1

例如

Bow("red")

正在调用Bow构造函数。

此外,您应该按照与声明相同的顺序放置初始化程序。

于 2013-06-18T05:27:58.167 回答
1

初始化器

red(Bow("red"))

Bow使用参数“red”调用构造函数,然后red使用 new (anonymous)进行初始化Bow

于 2013-06-18T05:30:48.370 回答
0

编码

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

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

而且您的术语有点令人困惑:C++ 11 标准为您提供了完全不同的初始化列表......

于 2013-06-18T05:29:07.813 回答
0

Bow("red")会给你一个 class 的实例Bow

red(Bow("red"))表示redBow("red")

于 2013-06-18T05:31:26.717 回答
0

完成以下操作。

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" 的 Bow 构造函数,以在调用此构造函数期间初始化 m_blue 成员。

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

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

它创建了一个用值“red”初始化的临时 Bow 对象,然后使用 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);
于 2013-06-18T06:58:18.427 回答