为什么这段代码有效,发生了什么?

时间:2011-09-18 19:43:41

标签: c++

前段时间我看到了以下代码,没有人能回答我是什么,也不知道它。 我使用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并且工作。

6 个答案:

答案 0 :(得分:3)

你的意思是初始化列表?这是您可以将父类和成员变量初始化为构造函数的一部分。

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

答案 1 :(得分:1)

 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

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

答案 2 :(得分:1)

这个特殊代码:

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

...或多或少等同于此代码:

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

正如其他人所指出的那样,后者被称为"initializer list"。虽然在这种情况下你可以这样做,但有时需要初始化列表(例如初始化基类)。

一个细微差别是以下不起作用:

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自我风格......只是为了避免混淆。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

  

请注意,我不会写明确:“name = newName”,

是的,你做的......只是以不同的方式。

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

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

(正如Kerrek SB在下面的评论中指出的,分配和初始化之间存在非常大的技术差异。请参阅@adpalumbo答案以获取初始化列表教程的链接)

答案 5 :(得分:0)

以下代码

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成员也是一个对象)。