您的位置:首页 > 编程语言 > C语言/C++

C++虚函数与函数重载理解分析

2014-08-12 09:47 218 查看
虚函数构建多态,函数重载通过以下方式: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()

正常。

主要还是函数的重写和重载,不能搞混了,不然结果很匪夷所思。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: