我在理解参考资料方面遇到了困难。考虑以下代码:
class Animal
{
public:
virtual void makeSound() {cout << "rawr" << endl;}
};
class Dog : public Animal
{
public:
virtual void makeSound() {cout << "bark" << endl;}
};
Animal* pFunc()
{
return new Dog();
}
Animal& rFunc()
{
return *(new Dog());
}
Animal vFunc()
{
return Dog();
}
int main()
{
Animal* p = pFunc();
p->makeSound();
Animal& r1 = rFunc();
r1.makeSound();
Animal r2 = rFunc();
r2.makeSound();
Animal v = vFunc();
v.makeSound();
}
结果是:“bark bark rawr rawr”。
按照 Java 的思维方式(这显然破坏了我对 C++ 的概念化),结果将是“bark bark bark bark”。我从我的上一个问题 https://stackoverflow.com/q/4403726/348056这种差异是由于切片造成的,我现在对切片是什么有了很好的理解。
但假设我想要一个返回 Animal 值的函数,该值实际上是 Dog。
- 我是否正确理解,我能得到的最接近的是参考?
- 此外,使用 rFunc 接口的人是否有责任查看返回的引用是否分配了 Animal& ? (或者故意将引用分配给 Animal,通过切片,丢弃多态性。)
- 我究竟应该如何返回对新生成的对象的引用而不做我上面在 rFunc 中所做的愚蠢的事情? (至少我听说这是愚蠢的。)
更新:由于到目前为止每个人似乎都同意 rFunc 是非法的,这就提出了另一个相关问题:
如果我传回一个指针,如果是这种情况,我如何与程序员沟通该指针不是他们的,需要删除?或者,我如何传达指针随时可能被删除(从同一线程但不同的函数),以便调用函数不应该存储它(如果是这种情况)。这是通过评论来传达这一点的唯一方法吗?这看起来很马虎。
注意:所有这些都导致了我正在研究的模板化共享_pimpl 概念的想法。希望我能学到足够的知识,以便在几天内发布相关内容。
1)如果您正在创建新对象,您永远不想返回引用(请参阅您自己对#3的评论。)您可以返回一个指针(可能由std::shared_ptr
or std::auto_ptr
)。 (您也可以通过副本返回,但这与使用new
操作员;它也与多态性稍微不兼容。)
2) rFunc
是错的。不要那样做。如果你用过new
创建对象,然后通过(可选包装的)指针返回它。
3)你不应该这样做。这就是指针的用途。
EDIT(回应您的更新:)很难想象您所描述的场景。更准确地说,一旦调用者调用其他(特定)方法,返回的指针可能无效?
我建议不要使用这样的模型,但如果您绝对必须这样做,并且必须在 API 中强制执行此操作,那么您可能需要添加一个间接级别,甚至两个级别。示例:将真实对象包装在包含真实指针的引用计数对象中。引用计数对象的指针设置为null
当真实对象被删除时。这太丑了。 (可能有更好的方法来做到这一点,但它们可能仍然很丑陋。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)