织芜 2024-06-06 00:33 采纳率: 72%
浏览 2
已结题

C++建造者模式管理内存问题

CLion下构建运行,会提示程序停止工作,看来是管理内存出了问题,但是具体不知道在哪里


#include <iostream>
#include<map>
#include<string>
#include<memory>

using namespace std;

class AbstractWall{
public:
    virtual ~AbstractWall(){}
    virtual void appearence(string str,pair<int,int> p)=0;
    virtual void show()=0;
};

class PaintingWall:public AbstractWall{
public:
    virtual ~PaintingWall(){}
    virtual void appearence(std::string str, pair<int, int> p) override {
        arc.insert(make_pair(str,p));
        return;
    }
    virtual void show() override{
        cout<<"这一面墙上:"<<endl;
        for(auto it:arc){
            cout<<"在坐标("<<it.second.first<<","<<it.second.second<<")"<<"处画了"<<it.first<<endl;
        }
        cout<<endl;
        return;
    }
private:
    map<string,pair<int,int>> arc;
};

class AbstractDrawer{
public:
    virtual ~AbstractDrawer(){}
    virtual void draw()=0;
    virtual void paint()=0;

    AbstractWall* getWall(){
        return wall;
    }
protected:
    AbstractWall* wall;
};

class DrawerAndy:public AbstractDrawer{
public:
    virtual void draw() override{
        wall->appearence("黑色城堡", make_pair(12,12));
        return;
    }
    virtual void paint() override{
        wall->appearence("幻色飞蛾", make_pair(123,123));
        return;
    }
};

class DrawerPolok:public AbstractDrawer{
public:
    virtual void draw() override{
        wall->appearence("狂放线条", make_pair(324,143));
        return;
    }
    virtual void paint() override{
        wall->appearence("四棵大树", make_pair(113,43));
        return;
    }
};

class Director{
public:
    ~Director(){}
    Director(AbstractDrawer* d):Drawer(d){}
    AbstractWall* MakeArtwork(){
        Drawer->draw();
        Drawer->paint();
        return Drawer->getWall();
    }
private:
    AbstractDrawer* Drawer;
};

int main() {
    unique_ptr<AbstractDrawer>d1(new DrawerAndy);
    unique_ptr<Director>dir(new Director(d1.get()));
    unique_ptr<AbstractWall>wall(dir.get()->MakeArtwork());
    //unique_ptr<AbstractWall>wall(dir.MakeArtwork());
    //wall->show();
    //dir.MakeArtwork();

    //wall是d1的成员,非法析构
    //delete wall;
    //delete d1;
    return 0;
}

  • 写回答

2条回答 默认 最新

  • 阿里嘎多学长 2024-06-06 00:33
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    在您提供的代码中,有几个问题可能导致程序运行时出现异常。我将逐一指出并提供解决方案:

    1. Director类中的MakeArtwork函数返回的AbstractWall指针管理问题

      • Director类中的MakeArtwork函数应该返回一个指向AbstractWall的智能指针,而不是裸指针。这样可以确保资源被自动管理。
    2. unique_ptr的使用问题

      • unique_ptr的使用看起来是正确的,但需要确保不要返回裸指针,而应该返回unique_ptr<AbstractWall>
    3. DrawerAndy和DrawerPolok类中对AbstractWall指针wall的赋值和使用

      • DrawerAndyDrawerPolok类中,wall指针应该在构造函数中被赋值,而不是在Director类中赋值。
    4. 悬空指针或非法访问内存的情况

      • 需要确保wall指针在使用前已经被正确初始化。

    下面是修改后的代码示例:

    #include <iostream>
    #include <map>
    #include <string>
    #include <memory>
    
    using namespace std;
    
    // ... [其他类定义保持不变] ...
    
    class Director {
    public:
        Director(unique_ptr<AbstractDrawer>& d) : Drawer(move(d)) {}
        unique_ptr<AbstractWall> MakeArtwork() {
            Drawer->draw();
            Drawer->paint();
            return unique_ptr<AbstractWall>(Drawer->getWall());
        }
    private:
        unique_ptr<AbstractDrawer> Drawer;
    };
    
    // 修改DrawerAndy和DrawerPolok的构造函数,接受unique_ptr<AbstractWall>并赋值给wall
    class DrawerAndy : public AbstractDrawer {
    public:
        DrawerAndy(unique_ptr<AbstractWall>& wall) : wall(move(wall)) {}
        // ... [其他成员函数保持不变] ...
    };
    
    class DrawerPolok : public AbstractDrawer {
    public:
        DrawerPolok(unique_ptr<AbstractWall>& wall) : wall(move(wall)) {}
        // ... [其他成员函数保持不变] ...
    };
    
    int main() {
        unique_ptr<AbstractWall> wall(new PaintingWall());
        unique_ptr<AbstractDrawer> d1(new DrawerAndy(move(wall)));
        unique_ptr<Director> dir(new Director(move(d1)));
        unique_ptr<AbstractWall> finalWall = dir->MakeArtwork();
        finalWall->show();
    
        return 0;
    }
    

    注意事项

    • Director构造函数现在接受一个unique_ptr<AbstractDrawer>的引用,并使用std::move来接管所有权。
    • MakeArtwork现在返回一个unique_ptr<AbstractWall>
    • DrawerAndyDrawerPolok的构造函数接受一个unique_ptr<AbstractWall>的引用,并使用std::move来接管所有权。
    • main函数中,我们首先创建一个unique_ptr<AbstractWall>指向PaintingWall的实例,然后将其传递给DrawerAndy的构造函数。

    参考资料

    这些修改应该能够解决您遇到的问题。如果问题仍然存在,请检查是否有其他逻辑错误或未处理的异常。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月8日
  • 创建了问题 6月6日

悬赏问题

  • ¥15 python深度学习代码求跑
  • ¥100 对接美团闪购医药接口相关问题
  • ¥15 嵌入式软件电子烟开发
  • ¥15 职场 Excel 查重问题
  • ¥15 求怎么用idea2021.3.2创建web项目并配置tomcat
  • ¥100 or-tools的相关问题
  • ¥15 有可能用平板通过拓展坞来烧录程序吗(keil5的那种)
  • ¥15 状态图的并发态问题咨询
  • ¥15 PFC3D,plot
  • ¥15 VAE模型编程报错无法解决