C++ 返回包含函数中另一个对象的对象

C++ 返回包含函数中另一个对象的对象,c++,function,pointers,object,return,C++,Function,Pointers,Object,Return,为什么drawManifestoGlobal中的值在第一次调用cout后会发生变化?它看起来像canvas.panel.drawManifestoGlobal被破坏了-为什么 我怎样才能避开这件事 #include <iostream> class DrawManifestoGlobal { public: int value = 2; }; class Panel { public: void setDrawManifestoGlobal(DrawManifes

为什么drawManifestoGlobal中的值在第一次调用
cout
后会发生变化?它看起来像
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 (!!!)
}
#包括
类DrawManifestoGlobal{
公众:
int值=2;
};
班级小组{
公众:
void setDrawManifestoGlobal(DrawManifestoGlobal&_DrawManifestoGlobal);
DrawManifestoGlobal*DrawManifestoGlobal;
};
类画布{
公众:
画布(){};
画布(DrawManifestoGlobal _DrawManifestoGlobal);
DrawManifestoGlobal DrawManifestoGlobal;
专家组;
};
类塞德{
公众:
帆布doSerDe();
};
Canvas SerDe::doSerDe(){
DrawManifestoGlobal DrawManifestoGlobal;
drawManifestoGlobal.value=99;
帆布(drawManifestoGlobal);
返回画布;
}
画布::画布(DrawManifestoGlobal _DrawManifestoGlobal){
drawManifestoGlobal=\u drawManifestoGlobal;
panel.setDrawManifestoGlobal(drawManifestoGlobal);
}
void面板::setDrawManifestoGlobal(DrawManifestoGlobal&_DrawManifestoGlobal){
drawManifestoGlobal=&U drawManifestoGlobal;
}
int main(){
塞德塞德;
帆布;
canvas=serde.doSerDe();
std::cout值
为什么在第一次调用
cout
后,
drawManifestoGlobal
中的值会发生变化?它看起来像是
canvas.panel.drawManifestoGlobal
被破坏-为什么

drawManifestoGlobal
函数中的
doSerDe()
是一个局部变量,在作用域结束时过期,但您正在设置指向它的指针(
Panel::drawManifestoGlobal
)并将指针传递到函数外部(通过返回
canvas
)。因此,对于访问已破坏对象的值,您有未定义的行为。编译器完全有权为同一对象打印两个不同的值

如果您确实需要一个指针(您不需要),您将希望动态分配
drawManifestoGlobal
(最好使用
唯一的\u ptr

类面板{
公众:
void setDrawManifestoGlobal(std::unique_ptr_drawManifestoGlobal);
std::唯一的\u ptr drawManifestoGlobal;
};
Canvas SerDe::doSerDe(){
std::unique_ptr drawManifestoGlobal(make_unique());
drawManifestoGlobal.value=99;
返回{std::move(drawManifestoGlobal)};
}
void面板::setDrawManifestoGlobal(std::unique_ptr drawManifestoGlobal){
drawManifestoGlobal=std::move(_drawManifestoGlobal);
}
事实上,代码中的任何地方都不需要指针!

谢谢您的帮助!1)但是为什么DrawManifestoGlobal会被破坏?它会在画布中创建,然后(一个副本)Canvas被传递回main。该面板和DrawManifestoGlobal不应该一起使用吗?2)如果没有指针,面板的DrawManifestoGlobal的内部变量总是与Canvas的DrawManifestoGlobal中的值相同,那么有什么方法可以做到这一点呢?@Saro 1)它是在
Canvas
构造函数中创建的,但它的生命周期e绑定到构造函数的主体。函数主体
\u drawManifesttoGlobal
结束后,仍然有一个指向它的指针,在构造函数外部使用(在main中)。即使它是传入main的
Canvas
的副本,也只复制
Panel::drawManifestoGlobal
的内部指针,而不是它指向的对象。2)我不知道您希望其内部变量相同。在这种情况下,您应该使用指针。
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);
}