为什么这段代码可以工作,正在发生的事情的名称是什么

Why does this code work, and what is the name of what is happening?

本文关键字:是什么 段代码 代码 工作 为什么      更新时间:2023-10-16

前段时间我看到了下面的代码,没有人能回答我是什么,也不知道它。我使用Visual Studio 2010,作为c++,在保存为cpp的文件中(在win32 cmd程序的项目中),然后我声明以下内容:

class People {
private:
    string name;
    short age;
public:
    People (string name,short age) 
        : name(name),
          age(age) 
    {
        //
    }
    inline string getName(void) {return name;}
};
class Professor : public People {
private:
    int salary;
    int nAlunos;
public:
    Professor(string name, short age, int salary, int nAlunos) 
        : People(name,age),
          salary(salary),
          nAlunos(nAlunos) 
    {
       //
    }
};

为什么赋值可以工作?

请注意,我没有明确地写:name = newName,这些东西是自己工作的。

我也尝试过wxDev-CPP,并成功了。

你是说初始化列表吗?在这里,你可以初始化父类和成员变量作为构造函数的一部分。

http://www.cprogramming.com/tutorial/initialization-lists-c + + . html

 People (string name,short age) : name(name),age(age) {}
                               // ^^^^^^^^^^^^^^^^^^ Constructor Initialiser List 

name(name)是什么?

括号中的

name是作为构造函数参数接收的变量。括号前的name是People类成员变量。代码一起初始化接收到的类成员变量的参数。

Professor(string name, short age, int salary, int nAlunos) 
    : People(name,age),
    // ^^^^^^^^^^^^^^ Base class constructor with arguments being invoked

现在您需要以这种方式从派生类显式地调用带参数的构造函数。如果没有它,编译器将调用基类的默认构造函数(没有参数的构造函数)并导致错误。基类没有默认构造函数,编译器无法继续。

下面的代码:

class Foo {
private:
    int value;
public:
    void Foo (int newValue) {
        value = newValue
    }
}

…或多或少相当于以下代码:

class Foo {
private:
    int value;
public:
    void Foo (int newValue) : value (newValue) {
    }
}

正如其他人所指出的,后者称为"初始化列表"。在这种情况下,你可以用任何一种方法,有时需要一个初始化器列表(比如初始化基类)。

一个细微的差别是下面的代码不能工作:

class Foo {
private:
    int value;
public:
    void Foo (int value) {
        value = value
        // you'd have to write this.value = value
        // otherwise it assumes both mentions of value are to the argument
    }
}

另一方面,一个细微差别是初始化列表方法有特殊的作用域。它假设当"value"在括号内被提及时,它指的是参数…而结果隐式地存储在成员中:

class Foo {
private:
    int value;
public:
    void Foo (int value) : value (value) {
    }
}

你是否认为构造函数的参数应该有一个不同于它们将被赋值的字段的名称,这是一个品味和风格的问题。我自己喜欢newXXXnewYYY风格…为了避免混淆

它被称为初始化列表,只适用于构造函数。

注意我没有写explicit: "name = newName",

是的,你需要……只是方式不同而已。

 People (string name,short age) : name(name),age(age) {}

构造函数将name初始化为传入的name(与age相同)。

(正如Kerrek SB在下面的评论中指出的那样,赋值和初始化之间存在很大的技术差异。

以下代码

People (string arg_name, short arg_age)
    :
    name(arg_name),
    age(arg_age) 
{
    //
}

等价于

People (string arg_name, short arg_age)
{
    name = arg_name;
    age = arg_age;
}

区别在于第一段代码使用初始化列表,其中People对象的成员nameage是由直接初始化构造的,而name = arg_name (复制)arg_name分配给已经构造的对象的name成员(name成员也是对象)。