“this”参数的类型是const,但函数没有标记为const。

31

好的,我对C++还有点小白,在我的第二个作业中,我需要制作具有公共和私有参数的类等等。基本上,修改器函数不起作用,因为它们显然不是const类型?

这是包含类的头文件:

class Customer {

private:
    string PhoneNumber_;
    string Name_;
    string Address_;

public:
    string get_PhoneNumber() const {return PhoneNumber_;} // Accessor
    const void set_PhoneNumber(unsigned x) {PhoneNumber_ = x;} // Mutator

    string get_Name() const {return Name_;}
    const void set_Name(unsigned x) {Name_ = x;}

    string get_Address() const {return Address_;}
    const void set_Address(unsigned x)  {Address_ = x;}
};

// declare the CreateCustomer function prototype with default values
Customer* CreateCustomer(const string& id = BLANK, const string& name = BLANK, const string& address = BLANK);

Customer* CreateCustomer(const string& id, const string& name, const string& address) {
    Customer* temp = new Customer();

    temp->get_PhoneNumber() = id; // Due to the Accessors and Mutators PhoneNumber, Name and Address are now functions
    temp->get_Name() = name;
    temp->get_Address() = address;

    return temp;
}

这是我在main.cpp文件中遇到的错误:

cout << "\n\nDear ";
    cout << Charge[0].Holder.set_Name() << " (" << Charge[0].Holder.set_PhoneNumber() << ")";  //  DisplayCustomer(customer) ;

    cout << ",\n" << Charge[0].Holder.set_Address() << "\n\n"

基本上,确切的错误信息是:

成员函数'set_Name'不可行:'this'参数的类型为'const Customer',但函数不是const类型

set_PhoneNumber和set_Address也会出现这种情况。非常感谢任何帮助!谢谢!

更新:我已经解决了。谢谢大家帮忙!


4
返回类型是 const void!? - Jarod42
如果你想要设置电话号码,CreateCustomer() 应该调用 set_PhoneNumber(id)。而且它的参数看起来需要是一个字符串而不是无符号整数。 - Galik
2
你的错误信息已经很明显了。你不能在常量对象上调用非常量函数。然而,我看不到Charge或Holder是什么,也不知道你在哪里以及如何声明这些实体。 - Karlis Olte
什么是 ChargeHolder - M.M
2
不使用getter和setter怎么样? - RamblingMad
4个回答

9

如果你想设置一个值,使用set方法。get方法仅用于获取变量,而不是设置类的内部变量(如果它们是按照你所定义的方式定义的)。

正确的用法是:

Customer* CreateCustomer(const string& id, const string& name, const string& address) {
    Customer* temp = new Customer();

    temp->set_PhoneNumber( id );
    temp->set_Name( name );
    temp->set_Address( address );

    return temp;
}

此外,您需要修改方法的接口:
class Customer {

private:
    string PhoneNumber_;
    string Name_;
    string Address_;

public:
    string get_PhoneNumber() const {return PhoneNumber_;} // Accessor
    void set_PhoneNumber(const string& x) {PhoneNumber_ = x;} // Mutator

    string get_Name() const {return Name_;}
    void set_Name(const string& x) {Name_ = x;}

    string get_Address() const {return Address_;}
    void set_Address(const string& x)  {Address_ = x;}
};

由于您想设置字符串而不是数字。

在函数参数中使用const string&比使用string更好,因为它在将其作为参数传递时不会复制字符串。由于它是一个常量引用,您不必担心函数可能会操纵输入。


1
嗯,我认为你应该反过来使用 get set ...在 CreateCustomer 中,您应该使用 set 函数,并在将 Customer 打印到流时 - 您应该使用 get 函数。而且, set 函数应该接收 string ,而不是 unsigned
因此,最好使用 constructor ,而不是 set 函数,然后只有 get 函数。

我认为更重要的是提到,首先不应该存在set和get函数... - Puppy

1
  1. 在类声明中应该使用std::。请参阅为什么“using namespace std;”被认为是不好的实践?以了解原因。

  2. 您的set_方法接受unsigned参数。您无法将无符号整数赋值给字符串,例如PhoneNumber_ = x;。参数需要是字符串。

您需要更改成员,例如:

std::string get_PhoneNumber() const { return PhoneNumber_; } // Accessor
const void set_PhoneNumber(std::string const & x) { PhoneNumber_ = x; } // Mutator

  1. 当您编写 temp->get_PhoneNumber() = id; 时,您的意图显然是为了设置 PhoneNumber_ 的值,那么为什么要使用 get_ 方法呢?只需使用适当的 set_ 方法并编写 temp->set_PhoneNumber(id);

  2. 通常在 C++ 中避免使用指针。如果您真的需要指针,请使用智能指针,例如 std::unique_ptrstd::shared_ptr(仅在需要使用普通指针时才使用)。

  3. std::string“空白”默认值是一个空字符串,如

    std::string const & id = std::string{} 对我来说更清晰明了。

  4. 要创建具有空/空白成员字符串的类型为 Customer 的对象,您只需要执行 Customer customer_object;,因为存在隐式声明的默认构造函数,该函数使用 std::string 默认构造函数,这将导致为空字符串。

  5. 通常使用构造函数根据某些参数值创建对象。

你可以很容易地编写一个函数,它可以接收所有必需的值,并且可以像默认构造函数一样使用,只需添加类似以下内容的代码即可。
Customer(const std::string& id = std::string{}, 
  const std::string& name = std::string{}, 
  const std::string& address = std::string{})
  : PhoneNumber_(id), Name_(name), Address_(address)
{ }

给你的类添加初始化列表。查看另一个C++类初始化列表示例

查看另一个C++类初始化列表示例

  1. 为了封装性,通常要避免使用'直接' getter 和 setter 来揭示您的数据结构。

0
您已将PhoneNumber_,Name_和Address_声明为string。但在setter方法中,您传递的是unsigned (int)

另外,您颠倒了getter和setter的用法!

此外,setter的返回类型可以只是void而不是const void


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接