如果构造函数和析构函数可以获取和显示(打印)数据,为什么我们需要 getter 和 setter?



见下面的代码,我很困惑为什么我们需要getter和setter?

#include<iostream>
#include<cstring>
using namespace std;
class car
{
char name[30];
int price;
public:
void get_data(char* n,int p)
{
strcpy(name,n);
price=p;
}
void set_data()
{
cout<<"Name: "<<name<<endl;
cout<<"Price:"<<price<<endl;
}
///Lets add the idea of constructor
car()
{
cout<<"constructor has been called"<<endl;
}
car(char *n, int p)
{
cout<<"2nd constructor has been called"<<endl;
strcpy(name,n);
price=p;
}
~car()
{
cout<<"Name: "<<name<<endl;
cout<<"Price:"<<price<<endl;
}
};
int main()
{
car A("BMW",1000);
car B("Audi",2000);

}

我在问如果构造函数可以设置值并打印值,为什么我们需要 getter 和 setter? 为什么会有吸气手和二传手的想法?

你是对的,getter 和 setter 通常是非常糟糕的想法,这表明你的类的抽象是破碎的/不存在的。但你强调的原因并不是真的。

您需要仔细考虑每个类应该做什么。目标是每个类应该做一件事,然后它们应该是可组合的。这使您可以更轻松地创建新功能并维护现有代码。

例如,你的汽车类不是很好,因为它不允许我拥有我不想随机打印内容的汽车。这实际上是两个类 - 一个Car类和一个RandomlyPrintingContentCar。

但话又说回来,汽车类根本不是一个真正的类。它没有什么真正起作用的。它只是两个字段的方便聚合。而且有一堆蹩脚的 C 字符串和缓冲区溢出,甚至将其描述为方便也太慷慨了。

类很有用,因为它们可以具有抽象接口,允许您隐藏其数据成员的状态。这几乎直接排除了只为所有内容提供 getter 和 setter,因为这样什么都不会隐藏。不提供 getter(或者更常见的是,二传手(是一个非常强大的工具,也是使用类的要点之一。

构造函数确实可以设置类变量的值。但是,每个对象的生存期只能发生这种情况一次,因为构造函数仅在实例化对象时调用。如果用户想稍后在程序中更改变量的值怎么办?这就是二传手的用途。资源库允许更改类中的变量。您还希望 getter 在程序运行时的任何时候访问该变量。

至于析构函数,它们通常保留用于垃圾回收,不应用于获取和设置变量。

  1. 您的get_data不是让用户获取数据,而是设置对象的数据。更好的命名是getName((,setName(char *n(和getPrice((和setPrice(int p(。
  2. 考虑重载您的构造函数,现在您想对代码进行一些更改,例如 price 不能为负数或名称不能为 null。
  3. 更好的编码风格是:

    类车 { 字符名称[30]; 整数价格; 公共: 空集名称(字符 *n( { if(n == NULL( n = "; strcpy(name,n(;

    }
    void setPrice(int p)
    {
    if(p <0) p = 0;
    price = p;
    }
    int getPrice()
    {
    return price;
    }
    char * getName()
    {
    return name;
    }
    ///Lets add the idea of constructor with default values
    car()
    {
    cout<<"constructor has been called"<<endl;
    setPrice(0);
    setName(""):
    }
    car(char *n, int p)
    {
    cout<<"2nd constructor has been called"<<endl;
    setName(n);
    setPrice(p);
    }
    ~car()
    {
    cout<<"Name: "<<name<<endl;
    cout<<"Price:"<<price<<endl;
    }
    };
    
  4. 现在,如果 price 得到了更多的验证,则所有验证都将添加到一个函数 setPrice 中,而不是在每个构造函数中以不同的方式添加。名字也一样。

  5. 您的set_data只写给 cout。 如果以后你想输出到文件怎么办?所以最好有getPrice((并在main中使用它来写入cout。

相关内容

最新更新