C++ 如何实施工厂+;c+中的装饰图案+;11

C++ 如何实施工厂+;c+中的装饰图案+;11,c++,c++11,design-patterns,stl,smart-pointers,C++,C++11,Design Patterns,Stl,Smart Pointers,我决定研究/将Head-First设计模式的Java代码翻译成C++11,由于智能指针,我能够使用自动内存管理实现大多数模式。然而,我对其中一个例子有一个问题。这是我的密码: #include <iostream> #include <memory> class AbstractBase { public: virtual void foo() = 0; virtual ~AbstractBase() = default; }; class A : p

我决定研究/将Head-First设计模式的Java代码翻译成C++11,由于智能指针,我能够使用自动内存管理实现大多数模式。然而,我对其中一个例子有一个问题。这是我的密码:

#include <iostream>
#include <memory>

class AbstractBase {
public:
    virtual void foo() = 0;
    virtual ~AbstractBase() = default;
};

class A : public AbstractBase {
public:
    void foo() override { std::cout << "Class A: foo() called" << std::endl; }
};

class B : public AbstractBase {
public:
    void foo() override { std::cout << "Class B: foo() called" << std::endl; }
};

class FooDecorator : public AbstractBase {
public:
    FooDecorator(AbstractBase *pBase): mpBase(pBase) { }
    void foo() override
    {
        mpBase->foo();
        ++mNumberOfFooCalls;
    }
    static int getFooCalls() { return mNumberOfFooCalls; }

private:
    static int mNumberOfFooCalls;
    AbstractBase *mpBase;
};

class AbstractFactory {
public:
    virtual std::unique_ptr<AbstractBase> createA() = 0;
    virtual std::unique_ptr<AbstractBase> createB() = 0;
    virtual ~AbstractFactory() = default;
};

class CountingFactory : public AbstractFactory {
public:
    std::unique_ptr<AbstractBase> createA()
    {
        // auto pA = new A();
        // return std::unique_ptr<AbstractBase>(new FooDecorator(pA));
        std::unique_ptr<AbstractBase> pA(new A());
        return std::unique_ptr<AbstractBase>(new FooDecorator(pA.get()));
    }

    std::unique_ptr<AbstractBase> createB()
    {
        // auto pB = new B();
        // return std::unique_ptr<AbstractBase>(new FooDecorator(pB));
        std::unique_ptr<AbstractBase> pB(new B());
        return std::unique_ptr<AbstractBase>(new FooDecorator(pB.get()));
    }
};

int FooDecorator::mNumberOfFooCalls = 0;

int main()
{
    std::unique_ptr<AbstractFactory> pFactory(new CountingFactory());
    std::unique_ptr<AbstractBase> pObjA = pFactory->createA();
    std::unique_ptr<AbstractBase> pObjB = pFactory->createB();
    pObjA->foo();
    pObjB->foo();
    std::cout << "Foo called " << FooDecorator::getFooCalls()
              << " times." << std::endl;
}
另一方面,当我使用gcc 4.9.2编译代码并运行它时,我得到以下错误:

pure virtual method called
terminate called without an active exception
问题似乎是
计数工厂内的
唯一\u ptr
s。我的理解是,用于初始化修饰对象的指针被释放,它会导致未定义的行为(clangcase)或终止(gcc case)

因此,我决定使用原始指针并添加了(上面注释掉的)行:

auto-pA=newa();
return std::unique_ptr(新食品装饰器(pA));
自动pB=新B();
return std::unique_ptr(新食品装饰器(pB));
这样做,事情就成功了,我从两个编译器获得了预期的输出。但是,现在存在内存泄漏,必须删除分配

我几乎总能找到一个解决方案,用智能指针指向类似的问题,我正在努力找到解决这个问题的最佳方法。我还尝试将
unique_ptr
s替换为
shared_ptr
s,但没有效果,它没有起作用


我还能用不同的方法使用智能指针吗?或者我必须手动管理我在工厂内分配的内存(不是首选)?

崩溃的原因是您只需通过方法分配内部指针

std::unique\u ptr

但是是的,为了避免泄漏,你应该在你的FoodDecorator中也有一个独特的ptr


据我所知,您需要
foodcorator
来拥有
pBase
。您可以通过改变

AbstractBase *mpBase;

或者在C++14中:

return std::make_unique<FooDecorator>(new A());
return std::make_unique(新的A());

这能解决问题吗?如果可以,我们可以看到编译后的代码吗?这应该运行,但再次留下
delete
ing指针指向用户的责任。@unrationalPerson有趣,我得到了上面的结果。可能是因为我是苹果的Clang3.5。我试图在没有分配的地方坚持使用原始指针,但在本例中失败了。因此,教训可能是更多地使用智能指针。非常感谢你。
std::unique_ptr<AbstractBase> pB(new B());
return std::unique_ptr<AbstractBase>(new FooDecorator(pB.get()));
AbstractBase *mpBase;
std::unique_ptr<AbstractBase> mpBase;
return std::unique_ptr<AbstractBase>(new FooDecorator(new A()));
return std::make_unique<FooDecorator>(new A());