为什么第一次调用cout
后drawManifestoGlobal中的值会发生变化?看来canvas.panel.drawManifestoGlobal
被毁了-为什么?
我该如何解决?
#include <iostream>
class DrawManifestoGlobal {
public:
int value = 2;
};
class Panel {
public:
void setDrawManifestoGlobal(DrawManifestoGlobal & _drawManifestoGlobal);
DrawManifestoGlobal * drawManifestoGlobal;
};
class Canvas {
public:
Canvas() {};
Canvas(DrawManifestoGlobal _drawManifestoGlobal);
DrawManifestoGlobal drawManifestoGlobal;
Panel panel;
};
class SerDe {
public:
Canvas doSerDe();
};
Canvas SerDe::doSerDe() {
DrawManifestoGlobal drawManifestoGlobal;
drawManifestoGlobal.value = 99;
Canvas canvas(drawManifestoGlobal);
return canvas;
}
Canvas::Canvas(DrawManifestoGlobal _drawManifestoGlobal) {
drawManifestoGlobal = _drawManifestoGlobal;
panel.setDrawManifestoGlobal(drawManifestoGlobal);
}
void Panel::setDrawManifestoGlobal(DrawManifestoGlobal &_drawManifestoGlobal) {
drawManifestoGlobal = &_drawManifestoGlobal;
}
int main () {
SerDe serde;
Canvas canvas;
canvas = serde.doSerDe();
std::cout << canvas.panel.drawManifestoGlobal->value << std::endl; // prints 99
std::cout << canvas.panel.drawManifestoGlobal->value << std::endl; // prints 0 (!!!)
}
关于实施要求:Canvas拥有Panel和DrawManifestoGlobal,Panel本身具有指向Canvas的DrawManifestoGlobal的指针,因此,从Canvas发生的任何更改对Panel都是可见的。
答案 0 :(得分:1)
为什么第一次调用
drawManifestoGlobal
后cout
中的值会改变?看来canvas.panel.drawManifestoGlobal
被毁了-为什么?
drawManifesttoGlobal
函数内的 doSerDe()
是一个局部变量,该变量在作用域的末尾到期,但是您正在设置指向它的指针(Panel::drawManifestoGlobal
)并将该指针传递到函数(通过返回canvas
)。因此,对于访问已破坏的对象的值,您具有未定义的行为。编译器完全有权为同一对象打印两个不同的值。
如果确实需要(不需要)指针,则需要动态分配drawManifestoGlobal
(最好是unique_ptr
)。
class Panel {
public:
void setDrawManifestoGlobal(std::unique_ptr<DrawManifestoGlobal> _drawManifestoGlobal);
std::unique_ptr<DrawManifestoGlobal> drawManifestoGlobal;
};
Canvas SerDe::doSerDe() {
std::unique_ptr<DrawManifestoGlobal> drawManifestoGlobal(make_unique<DrawManifesttoGlobal>());
drawManifestoGlobal.value = 99;
return {std::move(drawManifestoGlobal)};
}
void Panel::setDrawManifestoGlobal(std::unique_ptr<DrawManifestoGlobal> drawManifestoGlobal) {
drawManifestoGlobal = std::move(_drawManifestoGlobal);
}
事实是,您在代码中的任何地方都不需要指针!