c++;当argumentname和variable name相等时,类setter设置不同的变量 我对C++完全陌生了,我发现了一些我不理解的东西,我找不到答案(我也确信它被问了很多,所以给我指出一个线程也会很好)。

c++;当argumentname和variable name相等时,类setter设置不同的变量 我对C++完全陌生了,我发现了一些我不理解的东西,我找不到答案(我也确信它被问了很多,所以给我指出一个线程也会很好)。,c++,variables,setter,scoping,C++,Variables,Setter,Scoping,示例代码: #include <iostream> class Car { int doors; public: void set_doors(int doors){ doors = doors; } int get_doors(){ return doors; } };

示例代码:

#include <iostream>

    class Car {
        int doors;

        public:
            void set_doors(int doors){
                doors = doors;
            }

            int get_doors(){
                return doors;
            }
    };

    int main()
    {
        Car ford;
        ford.set_doors(3);
        std::cout << ford.get_doors() << std::endl;
    } 
我对参数和要更改的变量使用了相同的名称。 如果我把代码改成

  void set_doors(int newdoors){
   doors = newdoors;
  }
一切都会很顺利

我的问题是: 当使用我想要修改的变量名和参数名时,代码为什么会这样做? 请用简单的方式解释;)

谢谢

最好的

当使用我想要修改的变量名和参数名时,代码为什么会这样做

因为C++的规则要求它这样做:局部变量和参数的名称“胜过”成员变量。您应该会在这个赋值上得到一个编译器警告,说明赋值无效(它将参数的值重新赋值给自己)

解决此问题的惯用方法之一如下:

this->doors = doors;

这是该语言允许您解决非限定名称可能引用多个内容的情况的方法。

您的代码具有未定义的行为,因为您试图读取未初始化的变量。在以下功能中:

doors
始终引用函数参数,而不是成员变量。换句话说,您自行分配函数参数,而
doors
成员变量保持不变。更糟糕的是,成员变量从未初始化。在
get_doors
中阅读它只会在您的机器上产生
9
。这个程序可以做任何事情

您可以这样修复setter函数:

void set_doors(int doors){
    this->doors = doors;
}
不过,您的类很容易被错误地使用,因为在
get\u doors
实际工作之前,您不必调用
set\u doors
。要在构造函数中将
doors
初始化为
0

class Car {
    int doors;

public:
    Car() : doors(0) {}

    void set_doors(int doors){
        this->doors = doors;
    }

    int get_doors(){
        return doors;
    }
};

一旦进入函数get_doors,参数“doors”就会隐藏成员变量“doors”。因此,赋值“doors=doors”基本上是将函数参数doors赋值给doors,而成员变量仍然没有定义

另外,我理想情况下不会这样设计类,而是在构造函数中设置类成员变量。
*

  • 班车{ 内部门;公共门: 轿厢(内门):门(门){} int get_door_count(){return doors;}}
*

请注意,在这种情况下,当使用成员初始化器语法时,编译器可以正确区分函数参数doors和成员变量doors。

您认为
doors=doors
的作用是什么?你希望编译器知道一个
doors
是函数参数,另一个是成员,哪一个是哪个?我不是来自与编译器有任何关系的语言,所以这对我来说并不明显。你说,这是因为编译器不知道如何区分这些值?不管是不是编译器,人们怎么知道哪个值是哪个值?作为补充说明,您可能应该在编译时启用所有警告。编译器确切地知道如何区分它们。它有一个规则。局部变量(参数)隐藏了非局部变量(成员)。它只是不知道您希望如何区分它们。它“知道如何继续”,但编译器的规则说,最接近的变量定义优先,这意味着您的两个
都引用了相同的内容—传入的值。显然,将其设置为自身不会导致任何问题,但这不是您想要的。@Christopha是的,编译器必须遵循非常具体的规则列表来决定由非限定标识符引用的对象。局部变量总是胜过成员标识符,但该语言通过使用
this->
限定成员,为您提供了一种“补偿”的方法。奇怪的是,使用MSVC 2013,您将不会收到编译器警告,即使使用
/W4
void set_doors(int doors){
    this->doors = doors;
}
class Car {
    int doors;

public:
    Car() : doors(0) {}

    void set_doors(int doors){
        this->doors = doors;
    }

    int get_doors(){
        return doors;
    }
};