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
'this' argument has type const but function is not marked const
提问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
You should use
std::
in the class declaration. See Why is “using namespace std;” considered bad practice?on the question why.Your
set_
methods takeunsigned
arguments. You cannot assign an unsigned to a string likePhoneNumber_ = x;
. The arguments need to be strings.
您应该
std::
在类声明中使用。请参阅为什么“使用命名空间 std;” 被认为是不好的做法?关于为什么的问题。你的
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
When you write
temp->get_PhoneNumber() = id;
your intention is clearly to setthe value forPhoneNumber_
, so why do you use the get_method? Just use the appropriate set_method and writetemp->set_PhoneNumber(id);
.Generally avoid pointers in C++. If you're really in need of a pointer use a smart pointer like
std::unique_ptr
orstd::shared_ptr
(if and only if you are required to use a plain pointer: use one).A 'blank'default value for a
std::string
is an empty string likestd::string const & id = std::string{}
Appears clearer to me.To create an object of type
Customer
with blank/empty member strings you do not need to do more thanCustomer customer_object;
since there is an implicitly declared default constructor which uses thestd::string
default constructor which results in an empty strign anyway.Usually a constructoris used to create an object depending on some arguments values.
当你写的时候,
temp->get_PhoneNumber() = id;
你的意图显然是为设置值PhoneNumber_
,那么为什么要使用get_方法呢?只需使用适当的set_方法并写入temp->set_PhoneNumber(id);
。通常避免在 C++ 中使用指针。如果您确实需要指针,请使用像
std::unique_ptr
or 之类的智能指针std::shared_ptr
(当且仅当您需要使用普通指针时:使用一个)。a 的“空白”默认值
std::string
是一个空字符串,例如std::string const & id = std::string{}
对我来说似乎更清楚。要创建
Customer
具有空白/空成员字符串类型的对象,您不需要做更多的事情,Customer customer_object;
因为有一个隐式声明的默认构造函数,它使用std::string
默认构造函数,无论如何都会导致空字符串。通常,构造函数用于根据某些参数值创建对象。
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++ 类初始化列表示例。
- For the sake of encapsulation you usually want to avoid using 'direct' getters and setters revealing your data structure.
- 为了封装起见,您通常希望避免使用“直接”getter 和 setter 来揭示您的数据结构。
回答by ForEveR
Ehm. I think you should use get
and set
in reverse way...
In CreateCustomer
you should use set
functions and when print Customer
to stream - you should use get
functions.
And set
functions should receives string
, not unsigned
.
嗯。我认为你应该以相反的方式使用get
和set
......在CreateCustomer
你应该使用set
函数时,当打印Customer
到流时 - 你应该使用get
函数。并且set
函数应该接收string
,而不是unsigned
.
And so, it will be better to use constructor
, instead of set
functions and then will be only get
functions.
因此,最好使用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 void
and not const void
.
此外,setter 的返回类型可以是 justvoid
和 not const void
。