分配给派生 class 的基 class 指针

Base class pointer assigned to derived class

我创建了基础 class 指针并为其分配了新的派生 class。

 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->f(1.0) 调用 Base 函数 f(double),但 pb->g() 似乎调用 Derived class 函数 g 但使用来自 Base class 的参数 i=10。为什么?

Kerrek SB在评论里都说了,我再细说一下。

一样,解析默认函数参数的机制发生在编译时。当编译器看到pb->g();,知道pb是一个Base*类型的指针,它会参考Base::g的声明,即

virtual void g( int i = 10);

结论是:

1- 缺少的参数 i 应设置为 10。这是编译时的决定。

2- 方法声明为 virtual,这意味着实际调用的方法取决于 pb 在 运行 时指向的对象.编译器将机制设置为在 运行 时分派对 g 的调用(通常通过 vtable 的间接调用)。由于在 运行 时间碰巧 pb 实际上指向类型为 Derived 的对象,因此调用方法 Derived::g