从const函数返回非const属性引用

时间:2017-12-05 19:39:28

标签: c++ reference

此代码有问题吗?

// Example program
#include <iostream>
#include <string>
#include <vector>

class A
{
public:
    A( std::vector<int>& ref ) : data(ref) {}

    std::vector<int>& getData() const { return data; }

private:
    std::vector<int>& data;
};

void modifyA( const A& a )
{
    a.getData().push_back(3);
}

int main()
{
    std::vector<int> foo;
    A a(foo);
    modifyA(a);
    std::cout << foo.size() << std::endl;
    std::cout << foo.front() << std::endl;
}

对我而言看起来不错,但是在使用类似方法部署更复杂的代码时,我在Android下遇到了未定义的行为。在某些时候,当通过这样的getter修改类的前一个成员(shared_ptr)时,类的成员(std::vector)会被破坏(shared_ptr变为{{ 1}},虽然它根本没有修改过)。我还看到上面的程序在某些时候在http://cpp.sh上返回了意外值但不一致。最后,我无法在MVCE中找出问题......

我只是想知道是否从const getter返回非const成员的非const引用可能是个问题。

1 个答案:

答案 0 :(得分:4)

此代码很容易导致未定义的行为。根据您在评论中所说的内容,考虑这个例子:

struct B {
  std::vector<int> vec;
  A a;
  B() : vec{}, a{vec} {}
};

int main() {
  const B b;

  auto& vec = b.a.getData();

  vec.push_back(0);
}

我有一个const对象,并且通过扩展,它的所有成员都是const。但是在这里我得到了一个对这些const对象之一的非const引用。没有警告,没有明显丑陋的演员。只是沉默的鼻子恶魔。

即使所有权从来都不是问题,但这只是非常容易出错。