虚函数构建多态,函数重载通过以下方式:1,const重载;2,形参表;
虚函数子类中,不能出现返回值不同的情况,除非返回值可以向上转换;
常对象优先调用const重载函数,非常对象优先调用普通函数;
以以下例子分析:
class sbs{
public:
virtual string foodType() const{};
};
class Base{
public:
virtual int f(int) const{
cout<<"Base::f()"<<endl;
return 1;
}
virtual void f(string) const{
cout<<"Base::f(string)"<<endl;
}
virtual sbs* f(int) {
cout<<"Base::sbs::f()"<<endl;
return &s;
}
virtual void g() const{}
private:
sbs s;
};
class Derival1:public Base{
public:
void g() const{}
};
class Derival2:public Base{
public:
int f() const{
cout<<"Derival2::f()"<<endl;
return 2;
}
};
class Derival4:public Base{
public :
int f(int) const{
cout<<"Derival4::f(int)"<<endl;
return 4;
}
};
class Derival3:public Base{
public :
class sbs3:public sbs{
};
sbs3* f(int){
cout<<"Derival3::f(int)"<<endl;
return &k;
}
private:
sbs3 k;
};
void tune(Base &i)
{
i.f(1);
}
int main()
{
string s("hello");
Derival1 d1;
Derival4 d4;
Derival2 d2;
tune(d1);
tune(d2);
tune(d4);
Derival3 d3;
tune(d3);
}
首先,base基类中定义了四个虚函数:
virtual int f(int) const;
virtual void f(string) const;
virtual sbs* f(int);
virtual void g() const;
第一个和第二个通过形参表进行重载,第一个和第三个通过const进行重载;
则VTABLE中就有四项表值,分别指向这四个函数;
观察Derival1类中,有四个和Base中一摸一样的四项VTABLE表项;
类Derival2中,对基类的int f(int) const进行了重载(因为传入参数不一样),为int f() const;所以Derival2中的表项比较Base多了一项int f() const;为5项;注意这里const不能省略,因为如果没有const,默认为virtual sbs* f(int)的重写,但是返回参数不同,导致编译出错。
类Derival3中重写了基类的virtual sbs* f(int),这里与base 的VTABLE表项区别就是virtual sbs* f(int);其他都一样都是四项
类Derival4中,由于重写了int f(int) const;所以Derival4和baseVTABLE表项的区别就只是int f() const这一项,其他的都一样;
观察运行结果:
Base::sbs::f()
Base::sbs::f()
Base::sbs::f()
Derival3::f(int)
只有Derival3是正常结果,为何?
因为这里
void tune(Base &i)
{
i.f(1);
}使用的是基本对象,而不是常对象,默认调用virtual sbs* f(int);
如果将tune改为
void tune(const Base &i)
{
i.f(1);
}
则结果是:
Base::f()
Base::f()
Derival4::f(int)
Base::f()
正常。
主要还是函数的重写和重载,不能搞混了,不然结果很匪夷所思。