我正在使用其他人的类,当我将它插入 vector 时它表现得很奇怪。它涉及一个成员变量,它是对另一个成员变量的引用。这是最小的独立示例:
#include <iostream>
#include <vector>
class Myclass {
public:
Myclass() : a(1.0) {}
float a;
float &a_ref = a;
void addOne() {
a = a + 1.0;
}
};
int main() {
Myclass instance1;
instance1.addOne();
//prints 2:
std::cout << "instance.a_ref is " << instance1.a_ref << std::endl;
std::vector<Myclass> vec;
Myclass instance2;
vec.push_back(instance2);
vec.at(0).addOne();
//prints 1;
std::cout << "vec.at(0).a_ref is " << vec.at(0).a_ref << std::endl;
return 0;
}
我是用g++
和-std=c++11
编译的,所以一时没注意到这个问题。我现在看到问题可能与合成的复制构造函数和引用成员有关。但我不确定的是:
- 为什么当对象在 vector 中时会有不同的行为?
- 为什么
g++
没有给出任何警告,使用 c++11 标准?
因为我很好奇,所以有一个额外的问题:
- 首先初始化什么,
a
还是a_ref
?
最佳答案
问题确实出在默认的复制构造函数上。默认的复制构造函数从源对象的成员中初始化所有成员。也就是说,默认的复制构造函数与此相同:
Myclass(const Myclass &src) :
a(src.a),
a_ref(src.a_ref)
{}
默认的复制构造函数会初始化所有成员,因此它会忽略任何类内初始化器。
这也是为什么插入 vector 会导致问题。 vec.at(0)
是作为 instance2
的拷贝创建的,这意味着 vec.at(0).a_ref
指的是 instance2.a
。您可以通过打印他们的地址 (live example) 轻松验证这一点。
关于引用类型的 C++11 成员变量, vector push_back 后的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28109083/