我在Addison Wesley常见问题解答中阅读以下声明.
注意:在某些情况下,按值传递对象可能很危险.通过引用到const传递对象通常比通过值传递它们更好.例如,如果目标类型是抽象基类,则pass-by-value将不起作用,并且如果参数的类具有派生类,则可能在运行时导致错误行为.但是,如果保证参数的类不具有派生类,并且被调用的函数需要使用本地副本,则pass-by-value可能很有用.
如果目标类型是Abstract类并且参数的类具有派生类,那么它在运行时的错误行为如何?复制构造函数是否解决了这个问题?如果是这样,怎么样?谢谢.
编辑:那么,上述陈述是否应该是"编译时的错误行为"?不是"运行时".
这里有两件事,你似乎在混淆它们:
1)如果目标类型是抽象类并且您按值传递,则不会出现运行时错误:它将不会编译,句点.
2)如果目标类型是具体但具有派生类,则会出现运行时错误.考虑这个例子:
#include <iostream>
struct A {
virtual void f() { std::cout << "A\n"; }
};
struct B : public A {
virtual void f() { std::cout << "B\n"; }
};
void func(A a){
a.f();
}
int main() {
func( B() );
}
Run Code Online (Sandbox Code Playgroud)
它汇编很好,但输出A.如果将参数更改为A&,则polymorphism按预期工作并B打印.这个问题被称为切片,关于它,这里有一个很好的问题.
作为一般经验法则,如果类具有任何虚函数,则应该a)将析构函数声明为虚拟,b)避免按值传递它.
我实际上避免通过值传递任何参数,除非我确定它是一个原始类型,如int.如果您正在编写模板,那么最好接受所有参数const T&.
如果目标类型是Abstract类并且参数的类具有派生类,那么它在运行时的错误行为如何?
它甚至不会编译."按值传递"意味着您将尝试将参数的抽象类部分复制到新对象.但是你不能创建一个带有抽象类的对象作为它的mosted派生类,因为它是抽象的.
| 归档时间: |
|
| 查看次数: |
1311 次 |
| 最近记录: |