getter方法中的const限定符

时间:2014-08-12 13:42:57

标签: c++

为什么getter和setter需要const限定符?好吧,我认为setter方法的一个原因是阻止value在允许减少错误的方法体中进行更改。对我来说看起来不太合理,只是因为这个原因?

我完全混淆了为什么我需要在getter方法中使用它?

class turbo
{
    int i = 10;
    public:
    void setI(const int value) {i=value}
    int getI()  const {return i;}
}

7 个答案:

答案 0 :(得分:3)

假设我有一个const turbo类型的变量。然后,我可以调用标记为const没有其他人的方法。此外,我可以确定对这种方法的调用不会改变turbo实例的状态。这是因为标记为const的成员函数无法更改成员变量或在其上调用非const方法。

因此,一般来说,吸气者可以const,因为他们不会改变对象的状态。塞特不应该是const。更好的是,完全避免编写setter,因为很难控制对象的内部一致性并且往往使多线程编程复杂化:在构造函数中尽可能多地设置。

这使您在程序稳定性方面有了显着的改进。这就是为什么C ++程序员尽可能争取const - 正确性的原因。

(当然C ++允许您使用const_castmutable删除这些好处,但这应该谨慎行事。)

答案 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对象上调用,而不具有该限定符的函数则不能。 因此,如果您实例化turboconst 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)

如果返回类型是复杂类,则有两种情况:

  1. 您正在返回一个成员,并且您只提供了查看的值,那么您应该添加const并按引用返回。 (#4)

  2. 您使用您的成员返回一些计算结果和临时结果,然后您应该按值返回,而不需要const(因为没有可用的参考结果)(#5)

  3. 你应该为成员函数签名添加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}}