C++-----------------多态

原创 2012年03月25日 20:48:18

1.当继承方式是public时,才会讨论多态。

    1)派生类的对象给基类的对象赋值

        Drived d;
	Base b;
	b = d;

	Base* p = new Base;
	*p = d;
        delete p;

    2)一个派生类可以当作基类引用来用

  • 派生类的对象初始化一个基类的引用
  • 派生类的对象作为函数的形参(基类的引用)

  • 派生类的对象作为函数的值返回,函数的返回值是一个基类的引用

    派生类的对象有两部分:一部分是基类的,另一部分是派生类。当派生类的对象作为一个基类的引用来使用的时候。这个派生类的对象就好像是一个基类的对象。换句话说,就是这个派生类的对象只能访问基类的部分而不能访问派生类的部分。

    值得注意的是,如果一个函数在基类里声明,在派生类里重写。派生类的对象作为基类的引用来调用这个函数,那么将调用基类版本的函数

    派生类的对象作为基类对象的引用,作为函数的形参或作为函数的返回值。都会保留派生类对象的属性,尽管它看上去像个基类的对象。

    Base& fun( Base& b )
    {
         Derived* p= new Derived;
         return *p;
    }
    
    Derived d;
    Base& b = fun(d);
    delete &b; 
    

   3)基类的指针指向派生类的对象

  • 基类的指针可以指向派生类的对象
  • 一个指向派生类的指针可以赋值给一个基类的指针
  • 派生类的指针可以当做基类的指针来作函数的形参
  •   派生类的指针可以当做基类的指针来返回 

	Derived d;
	Base* b = &d;

       Base* fun( Base* b )
      {
        Derived* p= new Derived;
        return p;
      }

      Derived d;
      Base* b = fun(&d);
      delete b;
4)派生类的指针可以引用为一个基类指针的引用。这种情况发生在,当一个派生类的指针以引用的形式传给函数,函数接受的类型是一个基类的指针的引用。在这种情况下,这个派生类的指针在这个函数里当作基类的指针来使用
 
    Base* fun( Base*& b )
    {
      Derived* p= new Derived;
      return p;
    }

    Derived* p1 = &d;
    fun(p1);
下面写一个例子来演示一下:

class Point
{
friend ostream & operator<<(ostream &,Point &);
public:
   Point(double xval=0,double yval=0)
   {
      x=xval;
      y=yval;
   }
   void print()
   {
      cout<<"Point:X:Y "<<x<<","<<y<<"\n";
   }
protected:
   double x;
   double y;
};
ostream & operator<<(ostream &os,Point &apoint)
{
	os<<"Point:X:Y "<<apoint.x<<","<<apoint.y<<"\n";
	return os;
}

class Circle:public Point
{
	friend ostream & operator<<(ostream &,Circle&);
public:
	Circle(double r=0,double xval=0,double yval=0):Point(xval,yval)
	{
		radius=r;
	}
	void print()
	{
		cout<<"Circle:radius:"<<radius<<endl;
		cout<<" Point:X:Y "<<x<<","<<y<<"\n";
	}
	double area()
	{
		return (3.1415926*radius*radius);
	}
protected:
	double radius;
};
ostream & operator<<(ostream & os,Circle & aCircle)
{
	os<<"Circle:radius:"<<aCircle.radius;
	os<<(Point&)aCircle<<"\n";
	return os;
}
int main(int argc, char *argv[])
{
	Point p(2,3);
	cout<<"Point p="<<p<<endl;
	Point pp(0,0);
	cout<<"Point pp="<<pp<<endl;
	Circle c(7,6,5);
	cout<<"Circle c="<<c<<endl;
	pp=p;
	cout<<"Point pp="<<pp<<endl;
	pp=c;
	cout<<"Point pp="<<pp<<endl;
	pp=(Point)c;
	cout<<"Point pp="<<pp<<endl;
	//c=(Circle)pp;
	Point*  pPoint;
        pPoint = &c;
        pPoint ->print();    
        ((Circle*) pPoint)->print();
        Point& r = c;
        r.print();
        ((Circle&)r).print();
	cout<<"Hello C-Free!"<<endl;
	return 0;
}

注意:

在这些情况下,通过这个指针,派生类的对象好像一个基类的对象。指针可以是基类的指针,也可以是基类的指针引用了派生类的指针。然而,这个对象并没有改变,始终是一个派生类的对象

另一方面,一个基类的对象不能当成一个派生类的对象来使用。值得注意的是,如果一个基类的对象给一个派生类的对象赋值是错误的或者是把一个基类的指针赋给一个派生类的指针,或者传一个基类的对象或引用,当作一个派生类来用

然而,如果一个基类的指针指向一个派生类的对象,它可以被显示的转换为指向派生类的指针。从而可以调用派生的成员函数。这种转换叫做向下转换。但是,向下转换在程序当中是有风险的,因为基类的指针不一定能确切的指向派生类的对象。标准c++提供了安全的转换方法

在这两种情况下,函数的形参的行为都是基类的行为,但是它们却又着很大的区别。我们可以声明一些函数,这些函数叫虚函数。有基类的版本和派生类的版本。靠虚函数来区分对象的真实身份,而不是引用或指针。


虚函数下章讲解。


   

C++多态模板

  • 2015年01月05日 22:54
  • 80KB
  • 下载

面向对象多态c++

  • 2013年04月16日 07:56
  • 436KB
  • 下载

C++(多态实现原理)函数重写,重载,重定义

多态的实现原理:          首先介绍下函数重写 重定义 重载的区别; 函数重写:          发生在父类和子类之间,子类将父类中的同名函数进行了覆盖,如果在函数前面含有virtual那么...

C++重点复习题(多态和继承).doc

  • 2014年04月10日 13:34
  • 54KB
  • 下载

C++ 补充-多态

  • 2013年05月17日 09:27
  • 909KB
  • 下载

c++——多态、继承、运算符重载综合例子代码

#include #include using namespace std; class A { private: char *name; public: A(char *n); ...

C++继承与多态例子

  • 2009年06月28日 17:13
  • 1.63MB
  • 下载

浅谈c++的精髓之继承和多态

  • 2016年09月10日 14:58
  • 89KB
  • 下载

C++之面向对象程序设计的基本特点(抽象、封装、继承、多态)

编写程序的目的就是描述和解决现实世界中的问题。第一步就是将现实世界中的对象和类如实的反映在程序中。 面向对象程序设计的主要特点:抽象、封装、继承、多态。 1、抽象 定义:对具体问题(对象)进行概括,抽...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++-----------------多态
举报原因:
原因补充:

(最多只允许输入30个字)