添加const正确性

时间:2013-04-22 12:38:13

标签: c++ const

我有一些代码是在不考虑const正确性的情况下编写的。是否有任何改变这种情况的情况

class X
{
public:
    X(X& rhs); // does not modify rhs
    ...
};

到这个

class X
{
public:
    X(const X& rhs);
    ...
};

会改变现有程序的行为吗?我知道这个更改将允许当前没有编译的代码进行编译,但是如果有任何已经编译的代码会改变它的行为的情况我感兴趣。

类似的问题,改变这个改变有什么好处吗?

class X
{
public:
    X(X& rhs); // does not modify rhs
    X(const X& rhs);
    ...
};

4 个答案:

答案 0 :(得分:2)

对于复制构造函数,我不这么认为。但请注意,通常,是的,const的声明可以影响调用哪个方法。想到的唯一例子是数组重载 - 参见例如this question

答案 1 :(得分:1)

实际上,复制构造函数应该是imho,总是将const引用作为其参数。

X(X& rhs) { } // does not modify rhs

这不允许复制const对象,因此以下代码将无法编译。 虽然非const对象可以作为const参数,但另一种方法是不可能的

X const test;
X new_x(test);

我无法想象为什么有人应该排除const对象的副本。

关于您要进行的更改: 复制构造函数是否依赖于任何定义为非const的X成员函数?

这将像魅力一样工作,但允许复制const对象:

class X
{
private:
  int a;
public:
  X(X &rhs) { a = rhs.value(); } 
  int& value (void) { return a; }
};

下一个示例将不会编译,因为rhs是const但value()不是const。

class X
{
private:
  int a;
public:
  X(X const &rhs) { a = rhs.value(); } 
  int& value (void) { return a; }
};

如果你想使你的类const正确,你可能需要检查整个类。 它应该只影响你的类内实现。因为我不知道外部代码应该依赖于类成员函数的“非常量”的情况。 除非在我的示例中由任何公共成员函数返回非const引用。

以下代码段将按预期执行。

class X
{
private:
  int a;
public:
  X(int const &b) : a(b) { }
  X(X const &rhs) { a = rhs.value(); } 
  int const & value (void) const { return a; }
};

但请注意,这会干扰任何代码,例如:

X test(100);
test.value() = 12;

这可以使用int& value (void) { return a; },但无法使用int const & value (void) const { return a; }。 你当然可以提供安全保障。

答案 2 :(得分:0)

由于您正在更改具有复制构造函数的类,我假设您可以检查复制构造函数代码。如果您可以进行此更改并且复制构造函数不会给出编译器错误,那么您可能很好。需要考虑的一个案例是复制赋值运算符的作用,因为没有保证会在优化代码中调用。因此,还要确保您的复制赋值可以使用const参数。

答案 3 :(得分:0)

djechlin在his answer中提出了一个重点,虽然有点不清楚,所以我会尝试更好地解释。

对象或引用的常量会影响重载决策。例如,如果您有一个基于const的成员函数重载的对象,则会选择不同的重载:

struct foo {
    void do_stuff();
    void do_stuff() const;
};

int main() {
    foo f;
    const foo& fr = f;

    f.do_stuff();   // calls non-const version
    fr.do_stuff();  // calls const version
}

现在,如果其中一个重载有副作用而另一个没有副作用,那么在更改签名后你会得到不同的行为,因为(或者更确切地说,即使)程序编译得很好