码迷,mamicode.com
首页 > 其他好文 > 详细

12-继承与多态(下)

时间:2014-10-04 17:16:16      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:重写与重载   多态   对象   c++   

一.重写与重载

   

class Parent
	{
	public:
		virtual  void func()
		{
			cout<<" void func()"<<endl;
		}
		virtual void func(int i)
		{
			cout<<" void func(int i)"<<endl;
		}
		virtual void func(int i,int j)
		{
			cout<<" void func(int i,int j)"<<endl;
		}
	};
	
class Child:public Parent
{
public:
	virtual void func(int a,int b)
	{
		cout<<" void func(int a,int b)"<<endl;
	}
	virtual void func(int i,int j,int k)
	{
		cout<<" void func(int i,int j,int k)"<<endl;
	}
};	

    函数重载:

           (1)必须在同一类中,也就是在同一个作用域中。

           (2) 子类无法重载父类的函数,父类同名函数被覆盖

              如: c.func();//错误,编译不过 

           (3)重载是在编译期间根据参数类型和个数决定调用函数的

    函数重写:
            (1) 必须发生在父类与子类之间

            (2) 并且父类与子类中的函数必须有完全相同的原型。

            (3) 使用 virtual 声明之后能顾产生多态

            (4) 多态是在运行期间根据具体对象的类型决定调用函数的

    对比: 一个是在编译期间决定的,一个是在运行期间决定的,所以重载的效率还是比重写的效率高。

 

二. 对虚函数的理解

     C++中多态的实现原理

         (1) 当类中声明虚函数时,编译器会在类中生成一个虚函数表

         (2)  虚函数表是一个存储类成员函数指针的数据结构

         (3)  虚函数表是由编译器自动生成与维护的

         (4)  virtual 成员函数会被编译器放入虚函数表中

         (5) 存在虚函数时,每个对象中都有一个指向虚函数表的指针。     


bubuko.com,布布扣

 

void run(Parent* p)
{
	p->func(1,2);
}

               通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确        定真正的应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数            的效率要低的多。

    注意: 处于效率的考虑,没有必要把所有的成员函数都声明为虚函数。

   对象中VPTR指针什么时候被初始化的?

        (1) 对象在创建的时候由编译器对VPTR指针进行初始化,

        (2) 只有当对象的构造完全结束后VPTR的指向才最终确定

        (3) 父类对象的VPTR指向父类虚函数表

        (4) 子类对象的VPTR指向子类虚函数表

class Parent
{
public:
	Parent()
	{
		this->func();
	}	
	virtual void func()
	{
		cout<<"virtual void Parent::func()"<<endl;
	}
};

class Child:public Parent
{
public:
	Child()
	{
		func();
	}
	void func()
	{
		cout<<"void Child::func()"<<endl;
	}	
};

int main()
{
	Child p;  
	p.func();
	return 0;
}

bubuko.com,布布扣


     结论: 构造函数中调用虚函数无法实现多态

三. 纯虚函数

     面向对象的抽象类

         (1) 抽象类可用于表示现实世界中的抽象概念

         (2) 抽象类是一种只能定义类型,而不能产生对象的类

         (3) 抽象类只能被继承并重写相关函数

         (4) 抽象类的直接特征是纯虚函数

      说明: 纯虚函数只声明函数原型,不定义函数体的虚函数。

    抽象类与纯虚函数

          (1) 抽象类不能用于定义对象

          (2) 抽象类只能用于定义指针和引用

          (3) 抽象中的纯虚函数必须被子类重写

class Shape
{
public:
	virtual double area()=0;
};

    area是纯虚函数, =0 告诉编译器这个函数故意只声明不定义。

class Shape
{
public:
    virtual double area() = 0;
};

class Rectangle : public Shape
{
    double m_a;
    double m_b;
public:
    Rectangle(double a, double b)
    {
        m_a = a;
        m_b = b;
    }
    
    double area()
    {
        return m_a * m_b;
    }
};

class Circle : public Shape
{
    double m_r;
public:
    Circle(double r)
    {
        m_r = r;
    }
    
    double area()
    {
        return 3.14 * m_r * m_r;
    }
};

void area(Shape* s)
{
    cout<<s->area()<<endl;
}

int main(int argc, char *argv[])
{
    Rectangle rect(2, 3);
    Circle circle(4);
    
    area(&rect);
    area(&circle);
 	return 0;
}

小结:

      (1) 函数重载与函数重写不同

      (2) 多态是通过虚函数实现的

      (3) 虚函数在效率上会有影响

      (4) 抽象类是通过纯虚函数实现的。     





12-继承与多态(下)

标签:重写与重载   多态   对象   c++   

原文地址:http://blog.csdn.net/u014304293/article/details/39779339

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!