【问题标题】:Base class pointer assigned to derived class分配给派生类的基类指针
【发布时间】:2017-08-02 20:37:28
【问题描述】:

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

 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) 调用基函数 f(double),但 pb->g() 似乎调用派生类函数 g,但使用基类的参数 i=10。为什么?

【问题讨论】:

  • 为什么?因为您静态使用Base 接口,所以向Derived::pb 的分派仅在运行时发生。
  • delete pb; 导致未定义的行为,因为 Base 没有虚拟析构函数

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


【解决方案1】:

Kerrek SB 在评论中都说了,我会详细说明一下。

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

virtual void g( int i = 10);

结论是:

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

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

【讨论】:

    猜你喜欢
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多