分配给派生 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
。
我创建了基础 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
。