我正在读一本书,说:如果函数你发送的参数有一个参数类型是一个抽象基类(ABC)如果函数参数类型是ABC,为什么不能传值工作?
通按值不起作用。你必须通过引用来传递参数(这将是一个派生类)。
我的问题是:
为什么你不按值传递派生类的说法?
C++中是否存在某些“内部”要求它作为参考?
这是做的方式动态绑定的作品?
我正在读一本书,说:如果函数你发送的参数有一个参数类型是一个抽象基类(ABC)如果函数参数类型是ABC,为什么不能传值工作?
通按值不起作用。你必须通过引用来传递参数(这将是一个派生类)。
我的问题是:
为什么你不按值传递派生类的说法?
C++中是否存在某些“内部”要求它作为参考?
这是做的方式动态绑定的作品?
为什么你不能按值传递派生类参数?
简而言之,如果你有一个函数,看起来像这样:
void foo(T t); // Takes a T by value
你这样调用它(无论v
是):
foo(v);
会发生什么事是,参数t
代表新的对象,它从参数v
复制初始化,就好像您在做:
T t = v;
现在,如果T
是抽象的,上面是非法的,因为你不能实例化一个抽象类(定义)。因此,参数foo()
不能从其参数中复制初始化。
C++中是否存在某些“内部”要求它作为参考?
就是这样的。 C++中的动态多态只能通过引用和指针来工作。当您尝试将派生类的对象分配给基类的对象时,您得到的是object slicing。
这是因为object slicing:按值接收的抽象类将收到您传递的对象的副本;因此,派生的数据成员将从其中分离出来,从而使对象无法使用。
当通过引用传递,要传递的现有对象,它是一个派生类的成员的地址,它的所有数据成员包括在内。这不是特定于C++ - 这是通常按值传递的属性。
的动态绑定以这样的方式被实现为不允许切片例如接听电话,好像它是一个完整的实例。 vtable指针被调整为将调用分派给抽象基类的成员函数。
您可以按值传递派生类。您无法将抽象基类作为参数传递,因为无法实例化抽象类。
一般而言,您希望通过引用或指针传递,因此您不会切片对象。这里有个很好的答案:What is object slicing?
当您按值收到对象时,其动态(其“真实”类型)类型是其静态类型。动态类型是抽象变量的变量是不可能的。不管你如何构建它。
你也可以使用指针。 – chris
http://en.wikipedia.org/wiki/Object_slicing – Lee
抽象类不能被实例化,所以“显然”你不能通过值来传递它们。此外,通过值传递不能很好地继承([切片问题](http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c))。 – syam