在工厂模式中使用智能指针
Using Smart Pointers with Factory Pattern
我正在尝试在工厂设计模式中使用智能指针。我进行了 google 搜索以获取一些想法,但找不到任何类型的实现,但有很多很棒的想法。所以,我写了自己的代码,但是有两点我不确定。
首先,我将添加我的代码,然后提出我的问题。
// AgentGameStyleFactory.hpp
#ifndef AgentGameStyleFactory_hpp
#define AgentGameStyleFactory_hpp
#include "AgentGameStyle.hpp"
#include <memory>
class AgentGameStyleFactory
{
public:
static std::unique_ptr<AgentGameStyle> instantiate(const AgentPlayingStyleData::ePLAYING_CHARACTER pStyle);
private:
static AgentGameStyle* instantiateHelper(const AgentPlayingStyleData::ePLAYING_CHARACTER pStyle);
};
#endif /* AgentGameStyleFactory_hpp */
// AgentGameStyleFactory.cpp
#include "AgentGameStyleFactory.hpp"
using namespace AgentPlayingStyleData;
std::unique_ptr<AgentGameStyle> AgentGameStyleFactory::instantiate(const ePLAYING_CHARACTER pStyle)
{
std::unique_ptr<AgentGameStyle> newStyle( instantiateHelper(pStyle) );
return std::move(newStyle);
}
AgentGameStyle* AgentGameStyleFactory::instantiateHelper(const ePLAYING_CHARACTER pStyle)
{
AgentGameStyle* newStyle = NULL;
switch(pStyle)
{
case ePLAYING_CHARACTER::ePC_CONTAIN:
newStyle = new ContainGameStyleAgent();
break;
case ePLAYING_CHARACTER::ePC_COUNTER:
newStyle = new CounterGameStyleAgent();
break;
case ePLAYING_CHARACTER::ePC_STANDARD:
newStyle = new StandardGameStyleAgent();
break;
case ePLAYING_CHARACTER::ePC_ATTACKING:
newStyle = new AttackGameStyleAgent();
case ePLAYING_CHARACTER::ePC_OVERLOAD:
newStyle = new OverloadGameStyleAgent();
break;
default:
newStyle = new StandardGameStyleAgent();
break;
}
return newStyle;
}
如你所见,我是在工厂中创建相关样式,然后返回并赋值为
mPlayingCharacteristic = AgentGameStyleFactory::instantiate(pPlayingCharacteristic);
其中 mPlayingCharacteristic
是 std::unique_ptr<AgentGameStyle>
我的第一个问题是关于返回 unique_ptr
。根据我读过的帖子,它似乎是正确的,但编译器 (Xcode) 给了我 "Moving a local object in a return statement prevents copy elision"
警告。这是正常的、我应该有的东西还是这里有问题?
我的第二个问题是我在 AgentGameStyleFactory.cpp
中启动 std::unique_ptr<AgentGameStyle> newStyle
是否正确,这意味着使用辅助方法 AgentGameStyleFactory::instantiateHelper
是正确的做法吗?
不需要 "helper method" 返回原始指针,也不需要手动调用 new
:
std::unique_ptr<AgentGameStyle>
AgentGameStyleFactory::instantiate(const ePLAYING_CHARACTER pStyle)
{
switch(pStyle)
{
case ePLAYING_CHARACTER::ePC_CONTAIN:
{
return std::make_unique<ContainGameStyleAgent>();
}
//...
default:
{
return std::make_unique<StandardGameStyleAgent>();
}
}
}
你的编译器警告你 return std::move(...)
是正确的 - 你可以(并且应该)简单地写:
return newStyle;
我鼓励您放弃单独的助手及其裸露 new
,直接创建智能指针(假设 C++14 或更高版本):
std::unique_ptr<AgentGameStyle> AgentGameStyleFactory::instantiate(const ePLAYING_CHARACTER pStyle)
{
switch(pStyle) {
case ePLAYING_CHARACTER::ePC_CONTAIN:
return std::make_unique<ContainGameStyleAgent>();
case ePLAYING_CHARACTER::ePC_COUNTER:
return std::make_unique<CounterGameStyleAgent>();
case ePLAYING_CHARACTER::ePC_STANDARD:
return std::make_unique<StandardGameStyleAgent>();
case ePLAYING_CHARACTER::ePC_ATTACKING:
return std::make_unique<AttackGameStyleAgent>();
case ePLAYING_CHARACTER::ePC_OVERLOAD:
return std::make_unique<OverloadGameStyleAgent>();
default:
return std::make_unique<StandardGameStyleAgent>();
}
}
我正在尝试在工厂设计模式中使用智能指针。我进行了 google 搜索以获取一些想法,但找不到任何类型的实现,但有很多很棒的想法。所以,我写了自己的代码,但是有两点我不确定。
首先,我将添加我的代码,然后提出我的问题。
// AgentGameStyleFactory.hpp
#ifndef AgentGameStyleFactory_hpp
#define AgentGameStyleFactory_hpp
#include "AgentGameStyle.hpp"
#include <memory>
class AgentGameStyleFactory
{
public:
static std::unique_ptr<AgentGameStyle> instantiate(const AgentPlayingStyleData::ePLAYING_CHARACTER pStyle);
private:
static AgentGameStyle* instantiateHelper(const AgentPlayingStyleData::ePLAYING_CHARACTER pStyle);
};
#endif /* AgentGameStyleFactory_hpp */
// AgentGameStyleFactory.cpp
#include "AgentGameStyleFactory.hpp"
using namespace AgentPlayingStyleData;
std::unique_ptr<AgentGameStyle> AgentGameStyleFactory::instantiate(const ePLAYING_CHARACTER pStyle)
{
std::unique_ptr<AgentGameStyle> newStyle( instantiateHelper(pStyle) );
return std::move(newStyle);
}
AgentGameStyle* AgentGameStyleFactory::instantiateHelper(const ePLAYING_CHARACTER pStyle)
{
AgentGameStyle* newStyle = NULL;
switch(pStyle)
{
case ePLAYING_CHARACTER::ePC_CONTAIN:
newStyle = new ContainGameStyleAgent();
break;
case ePLAYING_CHARACTER::ePC_COUNTER:
newStyle = new CounterGameStyleAgent();
break;
case ePLAYING_CHARACTER::ePC_STANDARD:
newStyle = new StandardGameStyleAgent();
break;
case ePLAYING_CHARACTER::ePC_ATTACKING:
newStyle = new AttackGameStyleAgent();
case ePLAYING_CHARACTER::ePC_OVERLOAD:
newStyle = new OverloadGameStyleAgent();
break;
default:
newStyle = new StandardGameStyleAgent();
break;
}
return newStyle;
}
如你所见,我是在工厂中创建相关样式,然后返回并赋值为
mPlayingCharacteristic = AgentGameStyleFactory::instantiate(pPlayingCharacteristic);
其中 mPlayingCharacteristic
是 std::unique_ptr<AgentGameStyle>
我的第一个问题是关于返回 unique_ptr
。根据我读过的帖子,它似乎是正确的,但编译器 (Xcode) 给了我 "Moving a local object in a return statement prevents copy elision"
警告。这是正常的、我应该有的东西还是这里有问题?
我的第二个问题是我在 AgentGameStyleFactory.cpp
中启动 std::unique_ptr<AgentGameStyle> newStyle
是否正确,这意味着使用辅助方法 AgentGameStyleFactory::instantiateHelper
是正确的做法吗?
不需要 "helper method" 返回原始指针,也不需要手动调用 new
:
std::unique_ptr<AgentGameStyle>
AgentGameStyleFactory::instantiate(const ePLAYING_CHARACTER pStyle)
{
switch(pStyle)
{
case ePLAYING_CHARACTER::ePC_CONTAIN:
{
return std::make_unique<ContainGameStyleAgent>();
}
//...
default:
{
return std::make_unique<StandardGameStyleAgent>();
}
}
}
你的编译器警告你 return std::move(...)
是正确的 - 你可以(并且应该)简单地写:
return newStyle;
我鼓励您放弃单独的助手及其裸露 new
,直接创建智能指针(假设 C++14 或更高版本):
std::unique_ptr<AgentGameStyle> AgentGameStyleFactory::instantiate(const ePLAYING_CHARACTER pStyle)
{
switch(pStyle) {
case ePLAYING_CHARACTER::ePC_CONTAIN:
return std::make_unique<ContainGameStyleAgent>();
case ePLAYING_CHARACTER::ePC_COUNTER:
return std::make_unique<CounterGameStyleAgent>();
case ePLAYING_CHARACTER::ePC_STANDARD:
return std::make_unique<StandardGameStyleAgent>();
case ePLAYING_CHARACTER::ePC_ATTACKING:
return std::make_unique<AttackGameStyleAgent>();
case ePLAYING_CHARACTER::ePC_OVERLOAD:
return std::make_unique<OverloadGameStyleAgent>();
default:
return std::make_unique<StandardGameStyleAgent>();
}
}