为什么在第一次调用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的指针,以便Panel对Canvas所做的任何更改都是可见的。
最佳答案
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);
}
事实是您在代码中的任何地方都不需要指针!