'this' 参数的类型为 const 但函数未标记为 const

'this' argument has type const but function is not marked const

好吧,我对 C++ 有点菜鸟,在我的第二个作业中,我需要用 public 和私有参数等制作 classes。基本上是 mutator 函数不会工作,因为显然它们不是 const 类型?

这是头文件 class:

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"

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

Member function 'set_Name' not viable: 'this' argument has type 'const Customer', but function is not type const

set_PhoneNumber 和 set_Address 也会发生这种情况。任何帮助将不胜感激!谢谢!

更新: 我成功了。谢谢大家帮助我!

您已将 PhoneNumber_Name_Address_ 声明为 string
但是在 setter 方法中,您传递的是 unsigned (int)

此外,您还颠倒了 getter 和 setters 的用法!

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

嗯。我认为您应该以相反的方式使用 getset ... 在 CreateCustomer 中,你应该使用 set 函数,当打印 Customer 流式传输时 - 你应该使用 get 函数。 set 函数应该接收 string,而不是 unsigned

因此,最好使用 constructor,而不是 set 个函数,这样就只有 get 个函数。

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

正确的用法是:

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& 作为函数参数比字符串更好,因为在将字符串作为参数传递时不复制字符串。因为它是一个 const 引用,所以您不必担心函数会操纵输入。

  1. 您应该在 class 声明中使用 std::。请参阅 Why is “using namespace std;” considered bad practice? 关于为什么的问题。

  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. A 'blank' std::string 的默认值是空字符串,如

    std::string const & id = std::string{} 我觉得更清楚了。

  4. 要创建具有 blank/empty 成员字符串的 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)
{ }

给你的 class。再看一个 C++ Class Initialization List example.

再看一个C++ Class Initialization List example

  1. 为了封装,您通常希望避免使用“direct”getter 和 setter 来泄露您的数据结构。