C++ 如何实施工厂+;c+中的装饰图案+;11
我决定研究/将Head-First设计模式的Java代码翻译成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
#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());