标签:没有 virtual 默认参数 pac name 运行 动态 对象 针对
/****************************************************************************
静态绑定:对象在声明时采用的类型,在编译期既已确定
动态类型:通常指一个指针或引用目前所指对象的类型,是在运行期决定的
静态绑定:绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,
发生在编译期
动态绑定:绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,
发生在运行期
在C++中,非虚函数一般都是静态绑定,而虚函数都是动态绑定(如此才可实现多态性)
****************************************************************************/
#if 0
#include <iostream>
class A
{
public:
void func()
{
std::cout<<"A::func()\n";
}
};
class B : public A
{
public:
void func()
{
std::cout<<"B::func()\n";
}
};
class C : public A
{
public:
void func()
{
std::cout<<"C::func()\n";
}
};
int main()
{
C* pc = new C(); //pc的静态绑定类型和动态绑定类型均为C*
B* pb = new B(); //pb的静态绑定和动态绑定类型均为B*
A* pa = pc; //pa的静态绑定类型为A*,动态绑定类型为pc的类型C*
pa = pb; //将pa的动态绑定类型改为B*,其静态绑定类型仍为A*
C* pNull = NULL; //pNull静态绑定类型为C*
pa->func();
pc->func();
pNull->func();
return 0;
}
#endif
/*----------------------------------------------------------------------
结论:
1.如果基类A中的func函数不是虚函数,无论哪个指针对func的调用都是
在定义时的静态类型决定,早在编译期确定了.
2.同样空指针也能调用非虚函数而不报错,所以要做空指针检查,因此静
态绑定不能实现多态。
3.如果基类中的func函数是虚函数,那所有的调用都要等到运行是根据其
指向对象的类型才能确定,比起静态绑定自然是要有性能损失,但实现了多态。
4.引用同样适用。
建议:
绝对不要重新定义继承而来的非虚函数,因为这样导致函数调用由对象声明的
静态类型确定了,而和对象本身脱离了关系,没有多态,这也将给程序留下预知的
隐患和莫名奇妙的BUG.
在动态绑定中,要注意默认参数的使用,当缺省参数和virtual函数一起使用时,
一定要谨慎。
-------------------------------------------------------------------------*/
# include <iostream>
using namespace std;
class F
{
public:
virtual void func(int i = 1)
{
cout<<"F::func()"<<i<<endl;
}
};
class E : public F
{
public:
virtual void func(int i = 0)
{
cout<<"E::func()"<<i<<endl;
}
};
void main()
{
F* pf = new F();
E* pe = new E();
pf->func(); //F::func()1
pf = pe; //将pf的动态绑定类型改为E*
pf->func(); //E::func()1
}
/*----------------------------------------------------------------------------
注意:
绝对不要重新定义一个继承而来的virtual函数的缺省参数值,因为缺省参数值都是
静态绑定的,而virtual函数确实动态绑定.
-----------------------------------------------------------------------------*/
标签:没有 virtual 默认参数 pac name 运行 动态 对象 针对
原文地址:http://www.cnblogs.com/enumhack/p/7473065.html