假设我想编写应该在堆上分配异构对象的工厂方法并将它们返回给调用者。我正在考虑设计这样的API:
bool MakeEm(auto_ptr<Foo>& outFoo, auto_ptr<Bar>& outBar) {
...
if (...) {
return false;
}
outFoo.reset(new Foo(...));
outBar.reset(new Bar(...));
return true;
}
这允许呼叫者执行此操作:
auto_ptr<Foo> foo;
auto_ptr<Bar> bar;
MakeEm(foo, bar);
我的问题是:“这是不恰当的吗?如果没有,那么这样做的正确方法是什么?”
我能想到的替代方法包括返回struct
auto_ptr
个,或编写工厂API以获取原始指针引用。它们都需要编写更多的代码,后者在异常安全方面还有其他的代码。
答案 0 :(得分:4)
询问某事是惯用的可以得到一些非常主观的答案。 但总的来说,我认为auto_ptr是传达所有权的好方法,所以从类工厂回来 - 这可能是一件好事。 我想重构一遍,这样
答案 1 :(得分:1)
作为一般规则,如果涉及auto_ptr
,则不是惯用语。一般来说,结构也不是惯用的 - 通常,你会为每个函数创建一个函数,按值返回并在失败时抛出异常,如果需要共享变量,则将其作为对象。
答案 2 :(得分:1)
我们假设返回值false
表示“不要查看输出参数”。
然后我要做的就是摆脱bool返回值,返回一个包含所需auto_poin的结构或对,并在错误条件下返回throw
。
答案 3 :(得分:1)
通常当你有auto_ptr参数时,它们不是引用。
这是因为当您将某些内容传递给一个采用auto_ptr的函数时,您希望该函数具有所有权。如果您通过引用传递,它实际上不会占用该对象(可能需要该对象)。
这是一个微妙的观点,但最后你需要看看你的界面试图对用户说些什么。
此外,您似乎将其用作 out 参数 就个人而言,我从未见过这个用例(但我能看到它)只记录你要做的事情,更重要的是为什么。
答案 4 :(得分:1)
您不必编写自己的结构来返回两个值 - 您可以使用std :: pair。在这种情况下,返回两个值没有太多的语法开销。这个解决方案确实存在“.first”和“.second”不是非常具有描述性的名称的问题,但是如果涉及的类型和函数的名称使得意图足够清楚,那么这不一定是个问题。
如果您正在使用C ++ 0x,则可以使用unique_ptr insted of auto_ptr,调用者可以使用auto而不必键入更长的std :: pair&lt; std :: unique_ptr&lt; A&gt ;,std :: unique_ptr&lt; B&gt; ;取代。如果您不使用C ++ 0x,则可以考虑使用typedef代替。
如果你返回两个值,那么你将没有空间给bool。您可以使用C ++ 0x元组返回所有三个值。您还可以通过抛出异常或返回空指针来指示错误。假设错误是罕见/异常,我宁愿例外。
正如其他答案所指出的那样,通常最好有两个单独的函数,每个函数返回一个对象。如果你不能这样做,因为两个对象的初始化是密不可分的,那么你可以创建一个封装初始化的类。您可以传递必要的信息以使两个对象成为构造函数(需要异常来指示错误),然后在该类上有两个方法,每个方法产生一个对象。