为什么getter和setter需要const
限定符?好吧,我认为setter方法的一个原因是阻止value
在允许减少错误的方法体中进行更改。对我来说看起来不太合理,只是因为这个原因?
我完全混淆了为什么我需要在getter方法中使用它?
class turbo
{
int i = 10;
public:
void setI(const int value) {i=value}
int getI() const {return i;}
}
答案 0 :(得分:3)
假设我有一个const turbo
类型的变量。然后,我可以调用标记为const
和没有其他人的方法。此外,我可以确定对这种方法的调用不会改变turbo
实例的状态。这是因为标记为const
的成员函数无法更改成员变量或在其上调用非const
方法。
因此,一般来说,吸气者可以const
,因为他们不会改变对象的状态。塞特不应该是const
。更好的是,完全避免编写setter,因为很难控制对象的内部一致性并且往往使多线程编程复杂化:在构造函数中尽可能多地设置。
这使您在程序稳定性方面有了显着的改进。这就是为什么C ++程序员尽可能争取const
- 正确性的原因。
(当然C ++允许您使用const_cast
和mutable
删除这些好处,但这应该谨慎行事。)
答案 1 :(得分:1)
任何const
函数都承诺不修改该类的任何成员变量。对于吸气者来说,这是微不足道的,但以下原因是他们必须const
:
对于该类中的其他const
函数,它们也可能只使用const
函数。
如果你有一些功能:
int turbo::foo() const
{
int i = getI();
return 2 * i;
}
如果您的函数getI()
也不是const
,编译器会告诉您turbo::getI()
不是const
,因此foo()
不能是const
答案 2 :(得分:1)
如果您将参数限定为常量,则会向调用者显示您未能在函数内更改该参数。在你的情况下,这是无用的,因为int value
无论如何制作副本。但是,如果您使用引用int& value
或指针int* value
,则将其声明为const
是有意义的,否则调用者可能会认为value
将被修改。
参数列表后面的const
- 限定符具有不同的含义。
声明为const
的函数可以在该类型的const
对象上调用,而不具有该限定符的函数则不能。
因此,如果您实例化turbo
类const turbo x;
之类的对象,那么它只能在其上调用const
个成员函数。这意味着非修改成员函数,在您的情况下只有int getI() const;
而void setI(const int);
无法调用,因为它会修改声明为const
的对象。
因为复制过于昂贵的参数被声明为const
,如果它们没有被函数修改,以通知调用者他们可以假定不会对该对象进行任何修改。
虽然声明为const
的函数用于不修改调用它们的对象的操作,例如getter。
答案 3 :(得分:0)
这样您就可以将它与常量对象一起使用,并告诉编译器该对象未被更改
答案 4 :(得分:0)
const
限定符。以您的代码为例,如果它看起来像这样,则需要const
限定符:
class turbo
{
private:
int i;
public:
void setI(const int& value) {i=value;}
const int& getI() const {return i;}
};
在处理比int
“更复杂”的类型时,它通常会变得很方便。
成员函数上的const
限定符旨在阻止您(或其他用户)更改函数内的成员变量,如果这是您在设计类时的初衷。
答案 5 :(得分:0)
在这两个函数声明之间
void setI(const int value) {i=value}
int getI() const {return i;}
有很大的不同。
第一个函数声明等同于
void setI( int value);
并且两者都声明了相同的一个函数。对于这些函数,参数通过值传递,该值是使用参数的副本。原始论证本身不会改变。
这两个函数声明之间的唯一区别是在第一个函数的主体内部,参数被视为局部常量变量。但是,这些函数定义没有任何重要的内容。
对于getter,限定符const表示该函数可能不会更改对象的数据成员。你可能不会写例如
int getI() const {return ++i;}
这是限定符const表示在函数调用后对象的状态不会改变。
答案 6 :(得分:0)
进行了一些修改以演示setter / getter的几个条件:
class turbo
{
public:
void setI(int value) { i = value; } // #1
void setS(const std::string& value) { s = value; } // #2
int getI() const { return i; } // #3
const std::string& getS1() const { return s; } // #4
std::string getS2() const { return s + "blah"; } // #5
private:
int i = 10;
std::string s;
}
const
表示此getter无法修改它的所有者(即对象)。
const
表示无法在函数内部更改参数。
对于二传手:
如果参数是原生类型,则不需要const
,只需按值传递即可。 (#1)
如果参数是复杂类,请使用const
引用以避免不必要的临时对象构造。 (#2)
您无法为成员函数签名添加const
,因为您正在修改对象! (#1,#2)
对于getter:
如果返回类型是本机的,只需返回它,不需要const。 (#3)
如果返回类型是复杂类,则有两种情况:
您正在返回一个成员,并且您只提供了查看的值,那么您应该添加const
并按引用返回。 (#4)
您使用您的成员返回一些计算结果和临时结果,然后您应该按值返回,而不需要const
(因为没有可用的参考结果)(#5)
你应该为成员函数签名添加const
,因为getter意味着提供一些值,而不是修改对象。 (#4,#5)
在实践中,您可以尽可能通过const
引用传递对象,在这种情况下,使用您的对象的调用者只能使用您设计的const
成员函数,在这种情况下,它会使用// the function is called display, so it theoretically should not modify t
// so we pass t by const reference, therefore t can only call const member function
void display(const turbo& t)
{
std::string s = t.getS2();
// blahblah
}
成员函数非常可能为你的吸气剂
{{1}}