gpt4 book ai didi

c++ - 为什么指向基类的指针优于引用?

转载 作者:可可西里 更新时间:2023-11-01 17:10:38 24 4
gpt4 key购买 nike

通常,在 C++ 中,采用多态对象参数的函数代码采用指向它的指针似乎更可取:

class Base {};
class DerivedA : public Base {};
class DerivedB : public Base {};

void OperateOnObject(Base* obj) {};

vector<Base*> objects;
objects.push_back(new DerivedA());
objects.push_back(new DerivedB());

for (size_t i=0; i<objects.size(); i++) {
OperateOnObject(objects[i]);
}

为什么 OperateOnObject() 通常被编写为采用指向 Base 的指针而不是引用?切片是否存在潜在问题? (例如 vtable 丢失)

我看过 this response到一个听起来相似的问题,但它似乎没有解决同一个问题。

最佳答案

切片当然没有问题——你的类不需要虚表,因为它们没有虚函数,但即使它们有虚函数,按引用传递也不会复制对象,因此不会切任何东西。

您可以像通过指针一样通过引用进行虚拟调用。据我所知,没有实际原因,这只是为了风格。

可能是因为多态对象一般都是用new指针创建的,当然也必须通过指针(或智能指针)存储在容器中因为你不能有一个引用容器。始终通过指针操作它们可能看起来更一致。

另外,如果你想在像for_each这样的标准算法中使用OperateOnObject,那么要么它必须接受容器的元素类型,它是一个指针,否则你必须将它包装在一个执行取消引用的函数适配器中。标准 C++ 没有该适配器,因此要将您的样式基于它是一个很麻烦的世界。

相关:看看如果 OperateOnObject 获取一个引用并使用迭代器迭代 vector 会发生什么:

for (vector<Base*>::iterator i = objects.begin(); i != objects.end(); ++i) {
OperateOnObject(**i);
}

第 20 次双重间接让您烦恼或困惑,您将更改 OperateOnObject 的签名;-)

顺便说一句,一些风格指南警告不要传递非常量引用,无论该类型是否是多态基类,因为您无法立即区分 pass-by-reference 和 pass-by-在调用站点阅读代码时的值。所以他们更喜欢 OperateOnObject 无论如何都采用指针。

我个人认为这个论点有点弱——一个函数的名字应该大致告诉你它做了什么,特别是像 ChangeTheObject(my_object); 这样的语句并没有那么巧妙地暗示对我来说,因为它没有使用任何返回值,所以它必须改变它的参数。但我承认,如果您正确地遵循一种风格,那么清晰一致地将增变器与纯函数区分开来会有一些好处。

关于c++ - 为什么指向基类的指针优于引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10549886/

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