List/Vector 迭代器不会更改派生 class 中的 const 引用属性
List/Vector iterator wont change const reference attribute in a derived class
C++ 新手。我不知道(无法找到正确的搜索词)为什么会发生以下情况。
基本上 Parent
class 有一个成员 inputs
。 Child
class 有一个对 Parent::inputs
的 const 引用和一个 Child::set_inputs()
方法来改变 Parent::inputs
。当我有一个 std::list<Child>
或 std::vector<Child>
时,我遍历并尝试 set_inputs
,
Parent::inputs
改变,但 Child::input
不变。幕后发生了什么,我将如何解决这个问题?因为我需要使用 lists/vectors.
class Parent {
public:
Parent() = default;
protected:
double inputs;
};
class Child : public Parent {
public:
Child() = default;
void set_inputs(const double& X) {
inputs = X;
}
public:
const double& input = inputs;
};
int main() {
using std::cout;
using std::endl;
// Without Lists, works outputs '3.0'
double X1 = 3.0;
Child test0;
test0.set_inputs(X1);
cout << test0.input << endl;
// Neither Lists or Vectors work, does not output '3.0'
Child test1, test2, test3;
std::list<Child> test_lists = { test1, test2, test3 };
for (std::list<Child>::iterator t = test_lists.begin(); t != test_lists.end(); ++t) {
t->set_inputs(X1);
cout << t->input << endl;
}
}
默认的复制构造函数正在建立从一个实例到另一个实例的引用input
。当您将子对象放入容器时,您正在制作子对象的副本。换句话说,您的容器副本的 input
成员仍然引用您的 test1
、test
等实例的 inputs
成员。因此,当调用 set_inputs
更改实例 Parent::inputs
成员(正在发生)时,它与 input
中包含的 input
引用的 inputs
无关 Child
对象。注意:如果 test1
等在你的容器之前超出范围,这也是悬空引用的方法。
换句话说,默认的复制构造函数是这样做的:
Child(const Child& c) : Parent(c), input(c.input) {}
哎呀。现在 input
成员正在引用 c.input
引用的任何内容;不是 Parent::inputs
.
要查看不复制更改声明会发生什么,您可以这样做:std::list<Child> test_lists(3);
。现在,当您 运行 您的程序时,它将 运行 “正确”。没有正在制作的副本,因此 input
参考成员没有错误接线。
要解决此问题,您需要确保 input
成员始终固定到其父级 inputs
,包括复制操作者。简而言之,添加:
Child(const Child& c) : Parent(c), input(inputs) {}
到Child
class.
C++ 新手。我不知道(无法找到正确的搜索词)为什么会发生以下情况。
基本上 Parent
class 有一个成员 inputs
。 Child
class 有一个对 Parent::inputs
的 const 引用和一个 Child::set_inputs()
方法来改变 Parent::inputs
。当我有一个 std::list<Child>
或 std::vector<Child>
时,我遍历并尝试 set_inputs
,
Parent::inputs
改变,但 Child::input
不变。幕后发生了什么,我将如何解决这个问题?因为我需要使用 lists/vectors.
class Parent {
public:
Parent() = default;
protected:
double inputs;
};
class Child : public Parent {
public:
Child() = default;
void set_inputs(const double& X) {
inputs = X;
}
public:
const double& input = inputs;
};
int main() {
using std::cout;
using std::endl;
// Without Lists, works outputs '3.0'
double X1 = 3.0;
Child test0;
test0.set_inputs(X1);
cout << test0.input << endl;
// Neither Lists or Vectors work, does not output '3.0'
Child test1, test2, test3;
std::list<Child> test_lists = { test1, test2, test3 };
for (std::list<Child>::iterator t = test_lists.begin(); t != test_lists.end(); ++t) {
t->set_inputs(X1);
cout << t->input << endl;
}
}
默认的复制构造函数正在建立从一个实例到另一个实例的引用input
。当您将子对象放入容器时,您正在制作子对象的副本。换句话说,您的容器副本的 input
成员仍然引用您的 test1
、test
等实例的 inputs
成员。因此,当调用 set_inputs
更改实例 Parent::inputs
成员(正在发生)时,它与 input
中包含的 input
引用的 inputs
无关 Child
对象。注意:如果 test1
等在你的容器之前超出范围,这也是悬空引用的方法。
换句话说,默认的复制构造函数是这样做的:
Child(const Child& c) : Parent(c), input(c.input) {}
哎呀。现在 input
成员正在引用 c.input
引用的任何内容;不是 Parent::inputs
.
要查看不复制更改声明会发生什么,您可以这样做:std::list<Child> test_lists(3);
。现在,当您 运行 您的程序时,它将 运行 “正确”。没有正在制作的副本,因此 input
参考成员没有错误接线。
要解决此问题,您需要确保 input
成员始终固定到其父级 inputs
,包括复制操作者。简而言之,添加:
Child(const Child& c) : Parent(c), input(inputs) {}
到Child
class.