C++ 使用工厂模式的映射泄漏内存,解决方案? 类工厂 { 公众: Base*create(){return new Rand();} Base*create(双值){返回新的Op(值);} 基本*创建(常量标准::字符串和组件,基本*x,基本*y) { /* std::map\u CreateFuncs={ {“+”,新添加(x,y)}, {“-”,新的子(x,y)}, {“*”,新的Mult(x,y)}, {“/”,新的Div(x,y)}, {**,新战俘(x,y)} }; 返回(map_CreateFuncs.count(comp)==1)?map_CreateFuncs[comp]:nullptr; */ if(comp==“+”)返回新的Add(x,y); else if(comp==“-”)返回新的子项(x,y); else if(comp==“*”)返回新的Mult(x,y); else if(comp==“/”)返回新的Div(x,y); 否则如果(comp==“**”)返回新的Pow(x,y); 否则返回空ptr; } };
使用if/elseif有效~无内存泄漏。 但是我想使用我开始使用的map方法 想知道使用映射实现我的create(string,Base*,Base*)的正确方法是什么 我读过使用typedef的代码,但我不理解它的实现C++ 使用工厂模式的映射泄漏内存,解决方案? 类工厂 { 公众: Base*create(){return new Rand();} Base*create(双值){返回新的Op(值);} 基本*创建(常量标准::字符串和组件,基本*x,基本*y) { /* std::map\u CreateFuncs={ {“+”,新添加(x,y)}, {“-”,新的子(x,y)}, {“*”,新的Mult(x,y)}, {“/”,新的Div(x,y)}, {**,新战俘(x,y)} }; 返回(map_CreateFuncs.count(comp)==1)?map_CreateFuncs[comp]:nullptr; */ if(comp==“+”)返回新的Add(x,y); else if(comp==“-”)返回新的子项(x,y); else if(comp==“*”)返回新的Mult(x,y); else if(comp==“/”)返回新的Div(x,y); 否则如果(comp==“**”)返回新的Pow(x,y); 否则返回空ptr; } };,c++,memory-leaks,factory-pattern,C++,Memory Leaks,Factory Pattern,使用if/elseif有效~无内存泄漏。 但是我想使用我开始使用的map方法 想知道使用映射实现我的create(string,Base*,Base*)的正确方法是什么 我读过使用typedef的代码,但我不理解它的实现 >P>除非使用原始指针,否则默认情况下总是考虑使用 STD::UNQuYYPTPT/。使用智能指针既可以避免内存泄漏,又可以清楚地记录所有权模型。例如,当您创建Add(x,y)时,x和y的所有权应该转移到新创建的对象,还是应该与其他一些实例共享所有权?在后一种情况下,考虑 S
Add(x,y)
时,x
和y
的所有权应该转移到新创建的对象,还是应该与其他一些实例共享所有权?在后一种情况下,考虑<代码> STD::SysDypPTR < /代码> ./P>
class Factory
{
public:
Base* create() { return new Rand();}
Base* create(double value) { return new Op(value); }
Base* create(const std::string& comp, Base* x, Base* y)
{
/*
std::map<std::string, Base*> map_CreateFuncs = {
{ "+", new Add(x,y) },
{ "-", new Sub(x,y) },
{ "*", new Mult(x,y) },
{ "/", new Div(x,y) },
{ "**", new Pow(x,y) }
};
return (map_CreateFuncs.count(comp) == 1) ? map_CreateFuncs[comp] : nullptr;
*/
if (comp == "+") return new Add(x,y);
else if (comp == "-") return new Sub(x,y);
else if (comp == "*") return new Mult(x,y);
else if (comp == "/") return new Div(x,y);
else if (comp == "**") return new Pow(x,y);
else return nullptr;
}
};
类基{
公众:
virtual~Base()=0;
};
类添加:公共基{
公众:
静态std::unique_ptr create(std::unique_ptr x,std::unique_ptr y);
私人:
//构造函数是私有的,因此用户只能创建包含Add实例的智能指针。
添加(std::unique_ptr x,std::unique_ptr y);
};
阶级工厂
{
公众:
std::unique\u ptr create(常量std::string&comp,std::unique\u ptr x,std::unique\u ptr y)
{
使用FactoryMethod=std::function;
静态std::map\u CreateFuncs={
{std::string(“+”),FactoryMethod([](std::unique_ptr x,std::unique_ptr y){
返回Add::create(std::move(x),std::move(y));}),
//其他操作。。。
};
const auto factory_method_it=map_CreateFuncs.find(comp);
if(factory\u method\u it==map\u CreateFuncs.end()){
返回空ptr;
}
返回(工厂\方法\它->秒)(标准::移动(x),标准::移动(y));
}
};
请记住,
std::map
和std::function
可能会在简单的if
-else
子句上引入一些开销。可能使用lambda函数?不要使用new
。而是使用。它为您管理内存,因此不会泄漏。如果您不使用unique\u ptr
,则必须确定何时不再使用map
,并删除放入其中的所有对象。确定何时可以安全地删除。。。这是一个更烦人的编程问题,所以请使用unique\u ptr
和其他智能指针来为您解决它,并确保契约完成。关于返回(map\u CreateFuncs.count(comp)==1)?map_CreateFuncs[comp]:nullptr代码>您可以保存一个查找<代码>映射\u CreateFuncs.count(comp)==1)
搜索映射<代码>地图\u CreateFuncs[comp]
也会搜索地图<代码>自动查找=map\u CreateFuncs.find(comp)代码>是一个搜索。然后你返回找到的!=映射_CreateFuncs.end()*it:nullptr
也就是说,这可能根本不是您想要做的事情,如果您希望每次都返回一个新的Base
派生对象,就像人们期望从工厂返回的那样,这就不是您想要做的事情。不过,需要更多地了解您的用例才能做出合理的回答。注意:x
和y
可能比指针或unique\u ptr
更适合作为引用传递。但是为什么操作数也是从基派生的呢?在搜索google时,我发现很多函数在每个派生函数中都使用了静态创建方法。我用我的实现避免了这一点。std::函数对我来说是新的,我想它可以满足我的需求,非常感谢@用户4581301关于这一点你可能是对的,我将进行实验,看看是否可以通过引用传递它们。我不熟悉这个替换原则,所以谢谢你的链接!至于为什么它来自于基地;Base只是一个抽象类,从中添加/减去/多个/除/幂继承~这最初是为复合模式完成的,现在它使用相同的元素,但使用工厂模式。我会发布我的源代码,但我只能想象它会收到多坏^;特别是解析器非常丑陋,我不认为我可以通过引用传递x,y——因为它们从基继承,因此可以是复合的。它基本上变成一棵树,其中每个操作符都是一个具有lhs/rhs的节点。基址可以是运算符或操作数,其中lhs/RH为空PTR。
class Base {
public:
virtual ~Base() = 0;
};
class Add : public Base {
public:
static std::unique_ptr<Base> create(std::unique_ptr<Base> x, std::unique_ptr<Base> y);
private:
// Constructor is private so that the user can only create smart pointers holding instances of Add.
Add(std::unique_ptr<Base> x, std::unique_ptr<Base> y);
};
class Factory
{
public:
std::unique_ptr<Base> create(const std::string& comp, std::unique_ptr<Base> x, std::unique_ptr<Base> y)
{
using FactoryMethod = std::function<std::unique_ptr<Base>(std::unique_ptr<Base>, std::unique_ptr<Base>)>;
static std::map<std::string, FactoryMethod> map_CreateFuncs = {
{ std::string("+"), FactoryMethod([](std::unique_ptr<Base> x, std::unique_ptr<Base> y){
return Add::create(std::move(x), std::move(y)); })},
// Other operations ...
};
const auto factory_method_it = map_CreateFuncs.find(comp);
if (factory_method_it == map_CreateFuncs.end()) {
return nullptr;
}
return (factory_method_it->second)(std::move(x), std::move(y));
}
};