我创建了基类指针并为其分配了新的派生类。
class Base
{
public:
virtual void f( int );
virtual void f( double );
virtual void g( int i = 10 );
};
void Base::f( int )
{
cout << "Base::f(int)" << endl;
}
void Base::f( double )
{
cout << "Base::f(double)" << endl;
}
void Base::g( int i )
{
cout << i << endl;
}
class Derived: public Base
{
public:
void f( complex<double> );
void g( int i = 20 );
};
void Derived::f( complex<double> )
{
cout << "Derived::f(complex)" << endl;
}
void Derived::g( int i )
{
cout << "Derived::g() " << i << endl;
}
void main()
{
Base b;
Derived d;
Base* pb = new Derived;
b.f(1.0);
d.f(1.0);
pb->f(1.0);
b->g();
d->g();
pb->g();
delete pb;
}
结果是:
Base::f(double)
Derived::f(complex)
Base::f(double)
10
Derived::g() 20
Derived::g() 10
预计b和d的结果。 pb-&gt; f(1.0)调用基函数f(double),但pb-&gt; g()似乎调用Derived类函数g,但使用Base类中的参数i = 10。为什么呢?
答案 0 :(得分:2)
Kerrek SB在评论中说了这一切,我会详细介绍一下。
与this answer中一样,解析默认函数参数的机制发生在编译时。当编译器看到pb->g();
时,知道pb
是Base*
类型的指针,它会查询Base::g
的声明,即
virtual void g( int i = 10);
总结如下:
1-缺少的参数i
应设置为10.这是编译时的决定。
2-该方法被声明为 virtual ,这意味着实际调用的方法取决于pb
在运行时指向的内容。编译器设置机制以在运行时将调用分派给g
(通常通过vtable通过间接)。因为在运行时,pb实际上指向类型为Derived
的对象,所以调用方法Derived::g
。