C++获取对返回对象的引用
我需要通过引用来获取一个对象,我曾经这样做过:
MyObject& obj = FactoryThatGivesAnObject();
obj.MethodThatModifieObj();
不,我需要根据条件来做到这一点:
MyObject obj;
// Need obj to be a reference to the returned values below
if( foo )
obj = FactoryThatGivesAnObject();
else
obj = OtherFactoryThatGivesAnObject();
obj.MethodThatModifiesObj();
如何让 obj 成为第二个示例中的引用?
I need to grab an object by reference and I used to do it like so:
MyObject& obj = FactoryThatGivesAnObject();
obj.MethodThatModifieObj();
No I need to do it based on a conditional:
MyObject obj;
// Need obj to be a reference to the returned values below
if( foo )
obj = FactoryThatGivesAnObject();
else
obj = OtherFactoryThatGivesAnObject();
obj.MethodThatModifiesObj();
How can I have obj be a reference in the second example?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
与指针不同,引用只能设置一次。很多时候,这是一个有用的功能,但这是它令人沮丧的一个方面。您只想设置一次引用,但可能是不同的东西。
你有两个选择。
1) 使用三元运算符
如果您只处理两个工厂,并用一个简单的布尔值来决定使用哪个工厂,这通常是最简单的:
但是,如果
foo
更复杂,或者如果您有多个工厂选项,下一个选项可能会更干净。2) 使用您自己的工厂方法
请注意,您可能需要将几个参数传递给您的工厂方法:
References, unlike pointers, can only be set once. This is a useful feature many times, but this is the one frustrating aspect about it. You only want to set the reference once, but possibly to different things.
You have two options.
1) Use the ternary operator
This is often the easiest, if you're only dealing with two factories, and a simple boolean to decide which to use:
However, if
foo
is more complicated, or if you have multiple factory options, the next option may be cleaner.2) Use a factory method of your own
Note that you may need to pass several parameters to your factory method:
foo
- a simple boolean. As things grow, you may need additional criteria to help determine which factory to use.一种解决方案可能是使用三元运算符:
您也可以使用指针:
One solution may be to use a ternary operator:
You could also use a pointer:
你的第一句话就很可疑:
这应该如何运作?工厂方法无法返回对临时对象的引用,因此它可以返回的唯一合理的引用是动态创建的对象 - 但现在谁负责这个对象呢?
(除非您只是返回对现有对象的引用。但我假设您的工厂确实在创建新对象。)
此代码是内存泄漏车祸;我看不出有什么办法可以写出这样有意义的东西。更好的方法是在负责任的容器中返回新创建的对象,例如
shared_ptr
或unique_ptr
:这样,如果没有人拿起工厂产品,或者如果发生异常时,动态分配的对象将得到正确处理。
这也使得根据条件分配不同的指针变得很简单:
Your very first line is shady:
How is that supposed to work? The factory method cannot return a reference to a temporary, so the only sensible reference it could return is to a dynamically created object - but now who is responsible for this object?
(Unless you are just returning a reference to an existing object, that is. But I'm assuming that your factory is genuinely creating new objects.)
This code is a memory-leak car crash; I don't see any way to write anything sensible like that. A far better way is to return the newly created object in a responsible container, e.g. a
shared_ptr
or aunique_ptr
:That way, if nobody picks up the factory product, or if an exception occurs, the dynamically allocated object will get properly disposed of.
This also makes it trivial to assign different pointers depending on a conditional:
你不能。参考文献是别名;您只能通过将它们指向某物来创建它们,并且一旦您指向它们,就无法重新分配它们。
您可能最好在这里使用
std::auto_ptr
或std::unique_ptr
之类的东西。请注意,您的工厂需要返回 auto/unique_ptr 。如果您的工厂返回引用,我怀疑您可能会意外返回对未命名临时对象的引用(未定义的行为),但如果没有看到工厂的代码,就很难判断。You can't. References are aliases; you can only create them by pointing them at something, and once you've pointed them, they cannot be reassigned.
You would probably be better off using something like a
std::auto_ptr
orstd::unique_ptr
here. Note that your factory would need to return the auto/unique_ptr though. If your factory is returning a reference I suspect you might be accidentially returning references to unnamed temporaries (unedefined behavior), but without seeing the factories' code it's difficult to tell.这是一个解决方案,从技术上讲,它不是工厂,但解决了同样的问题 - 在更改参数时提供新对象:
此版本的优点是它不会将所有权传递给对象,但您仍然可以使用以下命令创建不同类型的对象:它。不过,两次调用 get_obj_a() 会导致问题,只有在需要该对象之前立即调用 get_obj_a() 时,它才有效。现在 if 语句可以放在工厂函数中。另外,还有另一种方法:
Here's one solution which is not technically a factory, but solves the same problem -- providing new objects when you change parameters:
This version has advantage that it does not pass around ownership to the object, but still you can create different kinds of objects with it. Two calls to get_obj_a() will cause problems though, it only works if you call get_obj_a() immediately before you need the object. Now the if statement can be put inside the factory function. Also here's another way to do it: