我正在尝试同时实现Singleton模式和Factory模式。
在我看来,每种工厂只能有一个基于抽象类的工厂,并使用该工厂产生相应的shape对象。

但是我得到一个错误:



我不知道为什么会这样。您能告诉我如何解决吗?
代码如下。

#include<type_traits>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<memory>
#include<time.h>
using namespace std;

class Shape
{
public:
    virtual void display();
protected:
    int x, y;
};

class MyTriangle:public Shape
{
public:
    MyTriangle(int _x, int _y)
    {
        x = _x;
        y = _y;
    }
    MyTriangle()
    {
        x = rand() % 200;
        y = rand() % 200;
    }
    void display()
    {
        printf("%d %d\n",x,y);
    }
};

class SuperFactory
{
public:
    virtual Shape* Execute() = 0;
};

class TriangleFactory :public SuperFactory
{
public:
    Shape* Execute()
    {
        Shape *p = new MyTriangle;
        return p;
    }
    static SuperFactory* GetFactory()
    {
        return instance;
    }
private:
    TriangleFactory()
    {
        instance = nullptr;
        instance = new TriangleFactory;
    }
    ~TriangleFactory(){}
    static TriangleFactory* instance;
};

int main()
{
    MyTriangle *p = dynamic_cast<MyTriangle*>(TriangleFactory::GetFactory()->Execute());
    p->display();
    return 0;
}

将不胜感激您的答案:)

最佳答案

我的批评:

  • 您不需要所有这些#include。您只能使用<iostream>逃脱。
  • 您的构造函数和解构函数是私有(private)的。我建议您:a。)改为保护它们,b。)仅将构造函数设为私有(private)。解构函数应该是公共(public)的和虚拟的。
  • 函数Shape::display应该声明为像SuperFactory::Execute这样的纯虚函数。更改为:virtual void display() = 0;
  • 其他答案的主要问题-在TriangleFactory* TriangleFactory::instance;函数之前简单地编写main()是:您会发现自己面临一个可爱的空指针错误。解决方案需要更改您的单例。因为您在构造函数中初始化了instance,并且在发布的代码中从未创建过TriangleFactory类型的对象,所以永远不会调用该构造函数,也永远不会初始化instance

  • 我的解决方案:

    TriangleFactory* TriangleFactory::instance;函数之前继续main(),但是像TriangleFactory* TriangleFactory::instance = nullptr;这样将其值设置为null。这样做可以避免与过去的内存泄漏有关的错误。

    不用在构造函数中初始化instance,而是将构造函数保留为空并将GetFactory函数更改为此:
    static SuperFactory *GetFactory()
    {
        if(!instance)
        {
            instance = new TriangleFactory();
            return instance;
        }
        else
        {
            return instance;
        }
    }
    

    现在,为什么我将TriangleFactory *TriangleFactory::instance = new TriangleFactory();放在main()之前(我怀疑​​您已经这样做了),可以改变所有的方法呢?好吧,初始化函数外部的任何数据都是有风险的。这些对象在运行时以任意顺序创建-当您开始创建依赖于其他类的类时,TriangleFactory *TriangleFactory::instance = new TriangleFactory();会在您的面前炸开。别把东西炸掉。 Get rid of cable and upgrade to DirecTV。没有xD只是在开 Jest ,但绝对不要TriangleFactory *TriangleFactory::instance = new TriangleFactory();

    10-08 05:04