完成以下操作。
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);