分配给派生类的基类指针

时间:2017-03-12 21:20:20

标签: c++ pointers derived-class virtual-method

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

 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。为什么呢?

1 个答案:

答案 0 :(得分:2)

Kerrek SB在评论中说了这一切,我会详细介绍一下。

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

virtual void g( int i = 10);

总结如下:

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

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