当argumentname和变量名相等时,c++类setter设置不同的变量

c++ class setter sets variables different when argumentname and variable name are equal

本文关键字:设置 setter 变量 c++ argumentname 变量名      更新时间:2023-10-16

我是c++的新手,我发现了一些我不理解的东西,但我找不到答案(而且我相信它已经被问了很多,所以给我指一个线程也很好)。

示例代码:

#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;
    } 

所以当我运行代码时,它总是返回一个长度为9的int。

我知道问题的发生是因为在

void set_doors(int doors) 

我要更改的参数和变量使用相同的名称。如果我想把代码改成

  void set_doors(int newdoors){
   doors = newdoors;
  }

一切都会完美运作。

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

感谢

最佳

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

因为C++的规则要求它这样做:局部变量和参数的名称"胜过"成员变量。你应该得到一个关于这个赋值的编译器警告,说这个赋值没有效果(它将参数的值赋值回自己)。

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

this->doors = doors;

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

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

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

doors总是引用函数参数,而不是引用成员变量。换句话说,您自分配函数参数,并且doors成员变量保持不变。更糟糕的是,成员变量从未初始化。在get_doors中读取它只能在您的机器上完全巧合地生成9。这个程序可以做任何事情。

你可以这样修复你的setter函数:

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

尽管如此,您的类很容易被错误地使用,因为在get_doors实际工作之前,不明显必须调用set_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,并且成员变量仍然未定义。

此外,理想情况下,我不会以这种方式设计类,而是在构造函数中设置类成员变量
*

  • Class Car{int门;公共:汽车(内部车门):车门(车门){}int get_door_count(){return doors;}}

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