2013-06-01 20 views
1

我正在读一本书,说:如果函数你发送的参数有一个参数类型是一个抽象基类(ABC)如果函数参数类型是ABC,为什么不能传值工作?

通按值不起作用。你必须通过引用来传递参数(这将是一个派生类)。

我的问题是:

为什么你不按值传递派生类的说法?

C++中是否存在某些“内部”要求它作为参考?

这是做的方式动态绑定的作品?

+0

你也可以使用指针。 – chris

+0

http://en.wikipedia.org/wiki/Object_slicing – Lee

+1

抽象类不能被实例化,所以“显然”你不能通过值来传递它们。此外,通过值传递不能很好地继承([切片问题](http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c))。 – syam

回答

5

为什么你不能按值传递派生类参数?

简而言之,如果你有一个函数,看起来像这样:

void foo(T t); // Takes a T by value 

你这样调用它(无论v是):

foo(v); 

会发生什么事是,参数t代表新的对象,它从参数v复制初始化,就好像您在做:

T t = v; 

现在,如果T是抽象的,上面是非法的,因为你不能实例化一个抽象类(定义)。因此,参数foo()不能从其参数中复制初始化。

C++中是否存在某些“内部”要求它作为参考?

就是这样的。 C++中的动态多态只能通过引用和指针来工作。当您尝试将派生类的对象分配给基类的对象时,您得到的是object slicing

6

这是因为object slicing:按值接收的抽象类将收到您传递的对象的副本;因此,派生的数据成员将从其中分离出来,从而使对象无法使用。

当通过引用传递,要传递的现有对象,它是一个派生类的成员的地址,它的所有数据成员包括在内。这不是特定于C++ - 这是通常按值传递的属性。

的动态绑定以这样的方式被实现为不允许切片例如接听电话,好像它是一个完整的实例。 vtable指针被调整为将调用分派给抽象基类的成员函数。

3

您可以按值传递派生类。您无法将抽象基类作为参数传递,因为无法实例化抽象类。

一般而言,您希望通过引用或指针传递,因此您不会切片对象。这里有个很好的答案:What is object slicing?

0

当您按值收到对象时,其动态(其“真实”类型)类型是其静态类型。动态类型是抽象变量的变量是不可能的。不管你如何构建它。

相关问题