gpt4 book ai didi

引用类型的 C++11 成员变量, vector push_back 后的不同行为

转载 作者:IT老高 更新时间:2023-10-28 22:19:28 25 4
gpt4 key购买 nike

我正在使用其他人的类,当我将它插入 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编译的,所以一时没注意到这个问题。我现在看到问题可能与合成的复制构造函数和引用成员有关。但我不确定的是:

  1. 为什么当对象在 vector 中时会有不同的行为?
  2. 为什么 g++ 没有给出任何警告,使用 c++11 标准?

因为我很好奇,所以有一个额外的问题:

  1. 首先初始化什么,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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com