C++ “this”参数的类型为 const,但函数未标记为 const

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32520642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:09:45  来源:igfitidea点击:

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

c++functionconstsettergetter

提问by Liam George

Okay so I'm a bit of a noob at C++ and in my second assignment I am required to make classes with public and private arguments etc, etc. Basically the mutator functions won't work because apparently they're not of type const?

好的,所以我对 C++ 有点菜鸟,在我的第二个作业中,我需要创建带有公共和私有参数等的类。基本上,mutator 函数将不起作用,因为显然它们不是 const 类型?

This is the header file with the 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;
}

And this is the error I get in the main.cpp file:

这是我在 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"

Basically, the exact error message is:

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

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

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

It happens with set_PhoneNumber and set_Address as well. Any help would be greatly appreciated! Thanks!

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

UPDATE:I got it working. Thanks everyone for helping me out!

更新:我让它工作了。感谢大家帮助我!

采纳答案by Gombat

If you want to set a value, use the set method. get Methods are only to obtain variables, not to set the inner variables of a class (If they are defined the way you did).

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

The correct usage is:

正确的用法是:

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

Also, you have to alter the interface of your methods:

此外,您必须更改方法的接口:

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

Since you want to set strings and not numbers.

因为你想设置字符串而不是数字。

Using const string&as function arguments is better than string to not copy the string when passing it as an argument. Since it is a const reference, you don't have to fear the function could manipulate the input.

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

回答by Pixelchemist

  1. You should use std::in the class declaration. See Why is “using namespace std;” considered bad practice?on the question why.

  2. Your set_methods take unsignedarguments. You cannot assign an unsigned to a string like PhoneNumber_ = x;. The arguments need to be strings.

  1. 您应该std::在类声明中使用。请参阅为什么“使用命名空间 std;” 被认为是不好的做法?关于为什么的问题。

  2. 你的set_方法需要unsigned参数。您不能将 unsigned 分配给像PhoneNumber_ = x;. 参数必须是字符串。

You'd need to change your members like

你需要改变你的成员

std::string get_PhoneNumber() const { return PhoneNumber_; } // Accessor
const void set_PhoneNumber(std::string const & x) { PhoneNumber_ = x; } // Mutator
  1. When you write temp->get_PhoneNumber() = id;your intention is clearly to setthe value for PhoneNumber_, so why do you use the get_method? Just use the appropriate set_method and write temp->set_PhoneNumber(id);.

  2. Generally avoid pointers in C++. If you're really in need of a pointer use a smart pointer like std::unique_ptror std::shared_ptr(if and only if you are required to use a plain pointer: use one).

  3. A 'blank'default value for a std::stringis an empty string like

    std::string const & id = std::string{}Appears clearer to me.

  4. To create an object of type Customerwith blank/empty member strings you do not need to do more than Customer customer_object;since there is an implicitly declared default constructor which uses the std::stringdefault constructor which results in an empty strign anyway.

  5. Usually a constructoris used to create an object depending on some arguments values.

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

  2. 通常避免在 C++ 中使用指针。如果您确实需要指针,请使用像std::unique_ptror 之类的智能指针std::shared_ptr(当且仅当您需要使用普通指针时:使用一个)。

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

    std::string const & id = std::string{}对我来说似乎更清楚。

  4. 要创建Customer具有空白/空成员字符串类型的对象,您不需要做更多的事情,Customer customer_object;因为有一个隐式声明的默认构造函数,它使用std::string默认构造函数,无论如何都会导致空字符串。

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

You could easily write one that takes all required values and can be used as a default constructo anyway by adding something along the lines of

您可以轻松地编写一个接受所有必需值的代码,并且无论如何都可以通过添加以下内容作为默认构造函数使用

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)
{ }

to your class. See another C++ Class Initialization List example.

到你的班级。请参阅另一个C++ 类初始化列表示例

See another C++ Class Initialization List example.

请参阅另一个C++ 类初始化列表示例

  1. For the sake of encapsulation you usually want to avoid using 'direct' getters and setters revealing your data structure.
  1. 为了封装起见,您通常希望避免使用“直接”getter 和 setter 来揭示您的数据结构。

回答by ForEveR

Ehm. I think you should use getand setin reverse way... In CreateCustomeryou should use setfunctions and when print Customerto stream - you should use getfunctions. And setfunctions should receives string, not unsigned.

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

And so, it will be better to use constructor, instead of setfunctions and then will be only getfunctions.

因此,最好使用constructor, 而不是set函数,然后将只是get函数。

回答by CinCout

You've declared PhoneNumber_, Name_and Address_as string.
But in the setter methods, you are passing unsigned (int)

您已声明PhoneNumber_Name_并且Address_作为string
但是在 setter 方法中,您正在传递unsigned (int)

Also, you have reversed the usage of getters and setters!

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

Also, the return types of setters can be just voidand not const void.

此外,setter 的返回类型可以是 justvoid和 not const void