此代码有问题吗?
// 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引用可能是个问题。
答案 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引用。没有警告,没有明显丑陋的演员。只是沉默的鼻子恶魔。
即使所有权从来都不是问题,但这只是非常容易出错。