gpt4 book ai didi

c++ - 学习 C++ : returning references AND getting around slicing

转载 作者:可可西里 更新时间:2023-11-01 15:19:30 24 4
gpt4 key购买 nike

我很难理解引用文献。考虑以下代码:

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”。我从我的 previous question 了解到这种差异是由于切片造成的,我现在对切片是什么有了很好的理解。

但是假设我想要一个返回真正是狗的 Animal 值的函数。

  1. 我是否正确理解我能得到的最接近的是引用
  2. 此外,使用 rFunc 接口(interface)的人是否有义务查看返回的引用是否分配了一个 Animal&? (或以其他方式故意将引用分配给 Animal,它通过切片丢弃多态性。)
  3. 我到底应该如何返回对新生成的对象的引用而不做我上面在 rFunc 中做的愚蠢的事情? (至少我听说这是愚蠢的。)

更新:因为到目前为止每个人似乎都同意 rFunc 是非法的,这会带来另一个相关问题:

如果我传回一个指针,如果是这种情况,我如何与程序员沟通该指针不是他们要删除的指针?或者我如何传达指针随时可能被删除(从同一个线程但不同的函数),以便调用函数不应该存储它,如果是这种情况。是通过评论传达这一点的唯一方法吗?这看起来很草率。

注意:所有这些都导致了我正在研究的模板化 shared_pimpl 概念的想法。希望我能在几天内学到足够的东西来发布一些相关的东西。

最佳答案

1) 如果您正在创建新对象,您永远不想返回一个引用(请参阅您自己对 #3 的评论。)您可以返回一个指针(可能由 std::shared_ptr 包装或 std::auto_ptr)。 (您也可以通过复制返回,但这与使用 new 运算符不兼容;它也与多态性略微不兼容。)

2) rFunc 是错误的。不要那样做。如果您使用 new 创建对象,则通过(可选包装的)指针返回它。

3) 你不应该这样做。这就是指针的作用。


编辑(响应您的更新:)很难想象您所描述的场景。一旦调用者调用其他(特定)方法,返回的指针可能无效会更准确吗?

我建议不要使用这样的模型,但如果您绝对必须这样做,并且必须在您的 API 中强制执行此操作,那么您可能需要添加一个间接级别,甚至两个。示例:将真实对象包装在包含真实指针的引用计数对象中。当实际对象被删除时,引用计数对象的指针设置为 null。这太丑了。 (可能有更好的方法,但它们可能仍然很丑。)

关于c++ - 学习 C++ : returning references AND getting around slicing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4405634/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com