实施4 多态性和虚函数

为了领积分哈!随便贴一段代码哈,O(∩_∩)O~!

一、理论介绍

C++编程语言的应用范围比较广泛,能够以一种简单灵活的方式帮助开发人员实现许多功能。在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生。
从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。

单继承的定义class B:public  {   < 派生类新定义成员> };  
多继承的定义  class C:public A,private B  {   < 派生类新定义成员>   }; 

公有继承(public)、私有继承(private)、保护继承(protected)是常用的三种继承方式。

  1. 公有继承(public)

公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。

  1. 私有继承(private)

私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。

  1. 保护继承(protected)

保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。

下面列出三种不同的继承方式的基类特性和派生类特性。

  public protected private
公有继承 public protected 不可见
私有继承 private private 不可见
保护继承 protected protected 不可见

在上图中:1)基类成员对派生类都是:共有和保护的成员是可见的,私有的的成员是不可见的。

                  
2)基类成员对派生类的对象来说:要看基类的成员在派生类中变成了什么类型的成员。如:私有继承时,基类的共有成员和私有成员都变成了派生类中的私有成员,因此对于派生类中的对象来说基类的共有成员和私有成员就是不可见的。

 
为了进一步理解三种不同的继承方式在其成员的可见性方面的区别,下面从三种不同角度进行讨论。

转自:

淮海工学院计算机科学系

#include<iostream>
#include<string>
using namespace std;

对于公有继承方式

(1) 基类成员对其对象的可见性:

公有成员可见,其他不可见。这里保护成员同于私有成员。

(2) 基类成员对派生类的可见性:

公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员。

(3) 基类成员对派生类对象的可见性:

公有成员可见,其他成员不可见。

所以,在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。这里,一定要区分清楚派生类的对象和派生类中的成员函数对基类的访问是不同的。

ector2,3,4类在DirectX中都有现成的可以调用,不过要实现其中的功能其实也不难,也都是一些简单的数学知识罢了。

实验报告书

    class fraction;
    //const fraction  operator=(const fraction
&f1,const fraction &f2);
    const fraction  operator+(const fraction &f1,const fraction &f2);
    const fraction  operator-(const fraction &f1,const fraction &f2);
    const fraction  operator*(const fraction &f1,const fraction &f2);
    const fraction  operator/(const fraction &f1,const fraction &f2);
    

对于私有继承方式

(1) 基类成员对其对象的可见性:

公有成员可见,其他成员不可见。

(2) 基类成员对派生类的可见性:

公有成员和保护成员是可见的,而私有成员是不可见的。

(3) 基类成员对派生类对象的可见性:

所有成员都是不可见的。

所以,在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承。

本文用C++实现一个简单的Vector3类的功能,暂时有的功能是:

 

class fraction
{
public:
    fraction(int aa,int bb);
    fraction();
    ~fraction();
    int getab(int a,int b);
    void const show();

对于保护继承方式

这种继承方式与私有继承方式的情况相同。两者的区别仅在于对派生类的成员而言,对基类成员有不同的可见性。

上述所说的可见性也就是可访问性。

关于可访问性还有另的一种说法。这种规则中,称派生类的对象对基类访问为水平访问,称派生类的派生类对基类的访问为垂直访问。

看看这样的例子:

#include<iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////////
class A      //父类
{
private:
    int privatedateA;
protected:
    int protecteddateA;
public:
    int publicdateA;
};
//////////////////////////////////////////////////////////////////////////
class B
:
public A     //基类A的派生类B(共有继承)
{
public:
    void funct()
    {
        int b;
        b=privatedateA;  //error:基类中私有成员在派生类中是不可见的
        b=protecteddateA;//ok:基类的保护成员在派生类中为保护成员
        b=publicdateA;   //ok:基类的公共成员在派生类中为公共成员
    }
};
//////////////////////////////////////////////////////////////////////////
class C
:
private //基类A的派生类C(私有继承)
{
public:
    void funct()
    {
        int c;
        c=privatedateA;   //error:基类中私有成员在派生类中是不可见的
        c=protecteddateA; //ok:基类的保护成员在派生类中为私有成员
        c=publicdateA;    //ok:基类的公共成员在派生类中为私有成员
    }
};
//////////////////////////////////////////////////////////////////////////
class D
:
protected A  //基类A的派生类D(保护继承)
{
public:
    void funct()
    {
        int d;
        d=privatedateA;  //error:基类中私有成员在派生类中是不可见的
        d=protecteddateA;//ok:基类的保护成员在派生类中为保护成员
        d=publicdateA;   //ok:基类的公共成员在派生类中为保护成员
    }
};
//////////////////////////////////////////////////////////////////////////
int main()
{
    int a;
 
    B
objB;
    a=objB.privatedateA;  //error:基类中私有成员在派生类中是不可见的,对对象不可见
    a=objB.protecteddateA;//error:基类的保护成员在派生类中为保护成员,对对象不可见
    a=objB.publicdateA;   //ok:基类的公共成员在派生类中为公共成员,对对象可见
 
    C
objC;
    a=objC.privatedateA;  //error:基类中私有成员在派生类中是不可见的,对对象不可见
    a=objC.protecteddateA;//error:基类的保护成员在派生类中为私有成员,对对象不可见
    a=objC.publicdateA;   //error:基类的公共成员在派生类中为私有成员,对对象不可见
 
    D
objD;
    a=objD.privatedateA;  //error:基类中私有成员在派生类中是不可见的,对对象不可见
    a=objD.protecteddateA;//error:基类的保护成员在派生类中为保护成员,对对象不可见
    a=objD.publicdateA;   //error:基类的公共成员在派生类中为保护成员,对对象不可见
 
    return 0;
}

构造函数和析构函数不能被继承

因此构造派生类的对象时,需要对基类数据成员.新增数据成员和成员对象的数据成员进行初始化

派生类构造函数的参数表部分既需要包含子类某些数据成员的初始值,也要包含基类的数据成员的初始值

如果基类没有默认的构造函数,那么派生类必须具有给基类构造函数提供参数的构造函数

派生类构造函数一般语法如下:

派生类名::派生类名(参数总表)  :基类名1(参数表1),...,基类名n(参数表n)  {  初始化语句  } 

当基类有多个构造函数时,编译器根据派生类构造函数为基类构造函数提供的参数初始化列表中的参数类型来确定调用哪个构造函数

派生类的析构函数应当首先对派生类新增普通成员进行清理

然后对派生类新增的对象成员进行清理

最后是对所有从C++类继承来的成员进行清理

1 + – * /算术运算

课程名:《 C++程序设计(二)》
 

    const fraction &  operator=(const fraction &f);
    friend const fraction  operator+(const fraction &f1,const fraction &f2);
    friend const fraction  operator-(const fraction &f1,const fraction &f2);
    friend const fraction  operator*(const fraction &f1,const fraction &f2);
    friend const fraction  operator/(const fraction &f1,const fraction &f2);
    
private:
    int a;//分子
    int b;//分母

二、实例讲解:

#include <iostream.h>

class Base
{
private:
        int b_number;
public:
        Base( ){}            // base第一个无参数的构造函数
        Base(int i) : b_number (i) { } //
Base有两个构造函数,且构造参数为b_number 
        int get_number( ) {return b_number;}
        void print( ) {cout << b_number << endl;}        
};

 派生类

class Derived : public Base
{
private:
       int d_number;

public:
// constructor, initializer used to initialize the base part of a
Derived object.
        Derived( int i, int j ) : Base(i), d_number(j) { };        //
派生类D从基类B及其自身的d_number中获得参数,进行构造

// 派生类D对基类B的函数进行重定义或叫隐藏

(重定义(也成隐藏)

(1)不在同一个作用域(分别位于派生类与基类)

(2)函数名字相同;
(3)返回值可以不同;
(4)参数不同。此时,不论有无 virtual
关键字,基类的函数将被隐藏(注意别与重载以及覆盖混淆) 。
(5)参数相同,但是基类函数没有
virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

重载(overload)
指函数名相同,但是它的参数表列个数或顺序,类型不同。但是不能靠返回类型来判断。
(1)相同的范围(在同一个作用域中) ;
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
(5)返回值可以不同;

重写(也称为覆盖
override)
是指派生类重新定义基类的虚函数,特征是:
(1)不在同一个作用域(分别位于派生类与基类) ;
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有 virtual 关键字,不能有 static 。
(5)返回值相同(或是协变),否则报错;<—-协变这个概念我也是第一次才知道…

(6)重写函数的访问修饰符可以不同。尽管
virtual 是 private 的,派生类中重写改写为 public,protected
也是可以的


        void print( ) 
        {
                cout << get_number( )
<< ” “;        
                // access number through
get_number( )
                cout << d_number
<< endl;
        }
};

int main( )
{
        Base a(2);// 定义一个基类
        Derived b(3, 4);// 定义一个派生类

  cout << “a is “;
        a.print( );                // print( ) in Base
        cout << “b is “;
        b.print( );                // print( ) in Derived
        cout << “base part of b is “; 
        b.Base::print( );                // print( ) in Base

        return 0;
}

 


没有虚析构函数,继承类没有析构
//Example: 
non- virtual destructors for dynamically allocated objects.

 #include
<iostream.h>

#include
<string.h>

class Thing
{ public:
virtual void what_Am_I( ) {cout << “I am a Thing./n”;}
~Thing(){cout<<“Thing destructor”<<endl;}
};

class Animal : public Thing
{  
public:
virtual void what_Am_I( ) {cout << “I am an Animal./n”;}
~Animal(){cout<<“Animal destructor”<<endl;}
};

void main( )
{
   Thing *t =new Thing;      
   Animal*x = new Animal;
   Thing* array[2];

array[0] = t;                                // base pointer

array[1] = x;               

for (int i=0; i<2; i++)  array->what_Am_I( ) ;

delete array[0];
   delete array[1];
   return ;
}

 


纯虚函数,多态

#include <iostream.h>
#include <math.h>

class Point
{
private:
        double x;
        double y;
public:
        Point(double i, double j) : x(i), y(j) { } 
        void print( ) const
        { cout << “(” << x << “, ” << y <<
“)”; }
};

class Figure
{
private:
        Point center;
public:
        Figure (double i = 0, double j = 0) : center(i, j) {
}         
        
Point& location( )
{
return center;
}                  // return an lvalue
   void move(Point p)
{
center = p;
draw( );
}

        virtual void draw( ) = 0; // draw the figure
        virtual void rotate(double) = 0; 
// rotate the figure by an angle                
};

class Circle : public Figure
{
private:
        double radius;
public:
        Circle(double i = 0, double j = 0, double r = 0) : Figure(i, j),
radius(r) { }
        void draw( )
        {
                cout << “A circle with center “;
                location( ).print( );
                cout << ” and radius ” << radius <<
endl;
        }
        void rotate(double)
        {
                cout << “no effect./n”;
        }        // must be defined
};

class Square : public Figure
{
private:
        double side;        // length of the side
        double angle;        // the angle between a side and the
x-axis
public:
        Square(double i = 0, double j = 0, double d = 0, double a =
0)        : Figure(i, j), side(d), angle(a) { }
   void draw( )
        {
                cout << “A square with center “;
                location( ).print( );
                cout << ” side length ” << side <<
“./n”  
                << “The angle between one side and the X-axis is ”
<< angle << endl;
        }
        void rotate(double a)
        {
               angle += a;
                cout << “The angle between one side and the X-axis
is ” << angle << endl;
        }
        void vertices( )
        {
                cout << “The vertices of the square are:/n”;
                // calculate coordinates of the vertices of the square
          }
};

int main( )
{
        Circle c(1, 2, 3);
        Square s(4, 5, 6);
   Figure *f = &c, &g = s;

        f -> draw( );
        f -> move(Point(2, 2));

        g.draw( );
          g.rotate(1);
        
s.vertices( );
// Cannot use g here since vertices( ) is not a member of Figure.

        return 0;
}
////////////////////////////////////////////////////////////////////
#include <iostream.h>
#include <string.h>

class Thing

public:
virtual void what_Am_I( ) {cout << “I am a Thing./n”;}

~Thing(){cout<<“Thing destructor”<<endl;}
};

class Animal : public Thing

public:
virtual void what_Am_I( ) {cout << “I am an Animal./n”;}

~Animal(){cout<<“Animal destructor”<<endl;}
};

void main( )
{
   Thing t ; 
        Animal x ;
   Thing* array[2];

   array[0] = &t;                        // base pointer
   array[1] = &x;        
          for (int i=0; i<2; i++)  array->what_Am_I( ) ;

   return ;
}

 


 

多继承

#include <iostream.h>

class A
{
private:
        int a;
public:
        A(int i) : a(i) { }
        virtual void print( )        {cout << a << endl;}
        int get_a( ) {return a;}
};

class B
{
private:
        int b;
public:
        B(int j) : b(j) { }
        void print( )        {cout << b << endl;}
        int get_b( ) {return b;}
};

class C : public A, public B
{
        int c;
public:
        C(int i, int j, int k) : A(i), B(j), c(k) { }//
C从A中得到参数i,从B中得到参数j,在c中得到k,实现多参数构造函数
        void print( )        {A::print( ); B::print( );}
        // use print( ) with scope resolution
        void get_ab( )        {cout << get_a( ) << ” ”
<< get_b( ) << endl;}
        // use get_a( ) and get_b( ) without scope resolution
};

int main( )
{
        C x(5, 8, 10);
        A* ap = &x;
        B* bp = &x;

ap -> print( );                // use C::print( );
       bp -> print( );                // use B::print( );
//    bp -> A::print( );                // as if x is inherited from
B only,
                                                // cannot access
A::print( );
        x.A::print( );                // use A::print( );
        x.get_ab( );

        return 0;
}

 


 

共同基类的多继承

#include <iostream.h>
class R
{int r;
public:
        R(int anInt){ r = anInt;};
       printOn(){ cout<<“r=”<<r<<endl;} ; };

class A : public R
{
int a;
public:
        A(int int1,int int2):R(int2){ a = int1;};};

class B : public R
{
int b;
public:
        B(int int1,int int2):R(int2){ b = int1;};};

class C : public A, public B
{
int c;
public:
C(int int1,int int2, int int3):A(int2,int3), B(int2,int3){ c = int1;}
};

int main( )
{    
  int i;
        R rr(10);      
A aa(20,30);      
B bb (40,50);
        C cc(5, 7, 9);
        rr.printOn();    
aa.printOn();                  //inherits R printOn  
bb.printOn();                   //inherits R printOn
        //cc.printOn();                  //would give error
        return 0;}

 


虚基类

 

#include <iostream.h>

class R
{ int r;
public:
        R (int x = 0) : r(x) { }   // constructor in R
        void f( ){ cout<<“r=”<<r<<endl;}     
        void printOn(){cout<<“printOn R=”<<r<<endl;}
};

class A : public virtual R
{  int a;
public:
        A (int x, int y) : R(x), a(y)  { } // constructor in A
        void f( ){ cout<<“a=”<<a<<endl;R::f();}
};

class B : public virtual R
{int b;
public:
        B(int x, int z) : R(x), b(z) { }// constructor in B
        void f( ){ cout<<“b=”<<b<<endl;R::f();}
};

class C : public A, public B
{ int c;
public:
// constructor in C, which constructs an R object first
C(int x, int y, int z, int w) : R(x), A(x, y), B(x, z), c(w) { }
        
void f( ){ cout<<“c=”<<c<<endl;A::f(); B::f();}
};

void main()
{  R rr(1000);
   A aa(2222,444);
   B bb(3333,111);
   C cc(1212,345,123,45);
   cc.printOn();     //uses R printOn but only 1 R..no ambiguity
   cc.f();                // shows multiple call of the R::f()
}

////////////////////////////////////////

#include <iostream.h>

class R
{ int r;
public:
        R (int x = 0) : r(x) { }   // constructor in R
        void f( ){ cout<<“r=”<<r<<endl;}
};

class A : virtual public R
{ int a ;
protected:
        void fA( ){cout<<“a=”<<a<<endl;};

public:
        A (int x, int y) : R(x), a(y)  { } // constructor in A
        void f( ) {fA( ); R::f( );}
};

class B : virtual public R
{  int b;
protected:
        void fB( ){cout<<“b=”<<b<<endl;};
public:
        B (int x, int y) : R(x), b(y)  { } // constructor in A
        void f( ) {fB( ); R::f( );}
};

class C : public A, public B
{ int c;

protected:
        void fC( ){ cout<<“c=”<<c<<endl;};        
public:
C(int x, int y, int z, int w) : R(x), A(x, y), B(x, z), c(w) { }

void f( )
        {  
                   R::f( );                    // acts on R stuff only
                A::fA( );            //acts on A stuff only
                B::fB( );                   // acts on B stuff only
                fC( );                  // acts on C stuff only
        }
};

void main()
{  R rr(1000);
   A aa(2222,444);
   B bb(3333,111);
   C cc(1212,345,123,45);
   cc.f();
}

 


 

私有继承

// Access levels

#include <iostream.h>

class Base
{
private:
        int priv;
protected:
        int prot;
        int get_priv( ) {return priv;}
public:
        int publ;
        Base( );
        Base(int a, int b, int c) : priv(a), prot(b), publ(c) { }
        int get_prot( ) {return prot;}
        int get_publ( ) {return publ;}
};

class Derived1 : private Base        // private inheritance
{
public:
        Derived1 (int a, int b, int c) : Base(a, b, c) { }
        int get1_priv( ) {return get_priv( );}
        // priv not accessible directly
        int get1_prot( ) {return prot;}
      int get1_publ( ) {return publ;}
};

class Leaf1 : public Derived1
{
public:
        Leaf1(int a, int b, int c) : Derived1(a, b, c) { }
        void print( )
        {
                cout << “Leaf1 members: ” << get1_priv( )
<< ” “
//                        << get_priv( )        // not
accessible
                        << get1_prot( ) << ” “
//                        << get_prot( )         // not
accessible
//                        << publ         // not accessible
                        << get1_publ( ) << endl;
        }  // data members not accessible.  get_ functions in Base not
accessible
};

class Derived2 : protected Base // protected inheritance
{
public:
        Derived2 (int a, int b, int c) : Base(a, b, c) { }
};

class Leaf2 : public Derived2
{
public:
        Leaf2(int a, int b, int c) : Derived2(a, b, c) { }
        void print( )
        {
                cout << “Leaf2 members: ” << get_priv( )
<< ” “
//                        << priv                 // not
accessible
                        << prot << ” “
                        << publ << endl;
        }  // public and protected data members accessible.  get_
functions in Base accessible. 
};

class Derived3 : public Base  // public inheritance
{
public:
        Derived3 (int a, int b, int c) : Base(a, b, c) { }
};

class Leaf3 : public Derived3
{

public:
        Leaf3(int a, int b, int c) : Derived3(a, b, c) { }
        void print( )
        {
                cout << “Leaf3 members: ” << get_priv( )
<< ” “
                        << prot << ” “
                        << publ << endl;
        }  // public and protected data members accessible.  get_
functions in Base accessible
};

int main( )
{
        Derived1 d1(1, 2, 3);
        Derived2 d2(4, 5, 6);
        Derived3 d3(7, 8, 9);

//        cout << d1.publ;                // not accessible
//        cout << d1.get_priv( );        // not accessible
//        cout << d2.publ;                // not accessible
//        cout << d2.get_priv( );        // not accessible
        cout << d3.publ;                // OK
        cout << d3.get_prot( );        // OK

        Leaf1 lf1(1, 2, 3);
        Leaf2 lf2(4, 5, 6);
        Leaf3 lf3(7, 8, 9);

//         cout << lf1.publ << endl;                    //
not accessible
//         cout << lf2.publ << endl;                // not
accessible
        cout << lf3.publ << endl;                 // OK

        return 0;
}

 


 

多级继承

// Point-Circle-Cylinder
#include <iostream.h>

// THE POINT CLASS

class Point
{
friend ostream & operator<<(ostream &,Point &);

public:
        
//  constructor
        Point (double xval =0, double yval=0 )
        { x=xval; y=yval;};  

protected:       // accessed by derived class
        double  x;
        double  y;
};

ostream & operator << (ostream & os,
                              Point &  apoint)
{
cout <<” Point:X:Y: “<<apoint.x << “,” 
                      << apoint.y<< “/n”;
  return os;  
}

//The Circle class  inherits from class Point

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)

//radius = r;
}

double area()

return (3.14159* radius *radius);
}

protected:
  double radius;
};

//note casting circle to point
ostream & operator <<(ostream & os, Circle & aCircle)
{
cout<< “Circle:radius:” << aCircle.radius;
os<< aCircle.x << “/n”; 
os<< aCircle.y << “/n”;        
return os;      
}

// THE CYLINDER CLASS
class  Cylinder  : public Circle
{
friend ostream & operator << (ostream & ,Cylinder &);

public:
Cylinder (double hv=0,double rv=0, 
                      double xv=0,double yv=0 )
                           : Circle( xv,yv,rv)
{
height = hv;
}        

double  area ( );

protected:     // may have derived classes
        double  height;
};

double Cylinder :: area ( )
{ // Note that cylinder area uses Circle area
return  2.0* Circle::area() + 2.0*3.14159* radius*height;
}

ostream & operator << (ostream & os,
                        Cylinder & acylinder)


cout << “cylinder dimensions: “;
  cout << “x: ” <<acylinder.x;
  cout << ”  y: ” <<acylinder.y ;
  cout << ”  radius: ” <<acylinder.radius ;
  cout << ”  height: ” <<acylinder.height 
                        << endl;
  return os; 
}

int main(void)
{
Point p(2,3);
Circle c(7,6,5);
Cylinder cyl(10,11,12,13);
cout << p;

cout << c;
cout << “area of cirle:” << c.area() << endl;

cout<< cyl;
cout<<“area of cylinder:”<< cyl.area()<<endl ;

cout<<“area of cylinder base is ”  
                 << cyl.Circle::area() << endl;

return 0;
}

 


 

protected
访问控制属性在继承的意义

 

//Example of treating derived class object as base class objects.
Point——Circle

#include <iostream.h>

// THE POINT CLASS

class Point

friend ostream & operator<<(ostream &,Circle&);
public:
Point (double xval =0, double yval=0 ) { x=xval; y=yval;};  

public:
void print()
{
cout <<” Point:X:Y: “<<x << “,” <<y<<
“/n”;
}

protected:       // accessed by derived class
double  x;    double  y;
};

ostream & operator << (ostream & os, Point &  apoint)
{
cout <<” Point:X:Y: “<<apoint.x << “,”<<
apoint.y<< “/n”;
  return os;  
}

//The Circle class  inherits from class Point
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.14159* radius *radius);};

protected:
double radius;
};

//note casting circle to point
ostream & operator <<(ostream & os, Circle & aCircle)
{
cout<< “Circle:radius:” << aCircle.radius;
cout<< (Point) aCircle << “/n”;           
return os;      
}

//We will look at a few main programs based on previous class
definitions. Casting and assignments

void main (void )
{
Point p(2,3);         cout <<“Point P=  “<< p;

Point pp(0,0);       cout <<“Point PP=  “<< pp;

Circle c(7,6,5);     cout <<“Circle c=  “<< c;       
//radius =7

pp = p;             cout <<“Point PP=  “<< pp;    //built in
assign =

// a circle is a member of the point class so assign a circle to a
point.

pp = c;           //legal; also assignment O.K.
cout <<“Point PP=  “<< pp;

pp= (Point) c;    // but better  use the cast
cout <<“Point PP=  “<< pp;  //note we get only the point
part of the Circle

//c = (Circle) pp;   //  illegal Cannot convert ‘class Point’ to ‘class
Circle’

//c=pp;                 //illegal assignment not defined

Point*  p;
p = &c;

P->print();    //call base class print
((Circle*)p)->print();

Point& r = c;
r.print();
((Circle&)r).print();

}

 


类的兼容性规则

 

#include <iostream.h>

class Base

public:  
void func( ) 
{cout << “Base class function./n”;} 
};

class Derived : public Base

public:  
void func( ) 
{cout << “Derived class function./n”;}
};

void foo(Base b)
{ b.func( ); }

int main( )
{
   Derived d;
   Base b;
   Base * p = &d;
   Base& br = d;

   b = d;
   b.func( );
   d.func( );
   p -> func( );
   foo(d);
   br.func( );

   return 0;
}

 

 


 
虚析构函数,防止内存泄露

 

 

#include <iostream.h>
#include <string.h>

class Base
{
protected:
        int id;
        char * name;
public:
        // default constructor
        Base(int a = 0, char * s = “”) : id(a)
        {
                if (!s) 

name = NULL; 
}
                else
                {
                        name = new char[strlen(s) + 1];
                        strcpy(name, s);
                }
                cout << “base default constructor/n”;
        }
                // copy constructor
        Base(const Base& b) : id(b.id)
        {
                if (!b.name) { name = NULL; }
                else
                { 
                        name = new char[strlen(b.name) + 1];
        strcpy(name, b.name);
}
                    cout << “base copy constructor/n”;
        } 
        // destructor
      ~Base( ) 
        {
            if( name != NULL )        delete [ ] name; 
                cout << “base destructor/n”;
        }
        const Base& operator= (const Base& b);                
friend ostream& operator << (ostream&, const Base&);
};

const Base& Base:perator= (const Base& b)
{
        if (this != &b)                        // Check if an object is
assigned to itself.
        {
             id = b.id;
                delete [ ] name;                //  Destroy the old
object.
                if (!b.name) { name = NULL; }
                else
                {
        name = new char[strlen(b.name) + 1];
        strcpy(name, b.name);
                }
        }
            cout << “base assignment operator/n”;
        return *this;
}

ostream& operator << (ostream& out, const Base& b)
{
        out << “Base member id = ” << b.id << endl;
        out << “Base member name = ” << b.name <<
endl;
        
        return out;
}

class Derived : public Base
{
private:
        float f;
        char * label;
public:
        // default constructor
        Derived(int a = 0, char * s = “”, float x = 0, char * t = “”)
: Base(a, s), f(x)
        {
                if (!t) { label = NULL; }
                else
                {
        label = new char [strlen(t) + 1]; 
        strcpy(label, t);
}
                cout << “derived default constructor/n”;
        }
        // copy constructor
        Derived(const Derived& d) : Base(d), f(d.f)
                // d used as an instance of Base
        {
                if(!d.label) { label = NULL; }
                else
                {
                        label = new char [strlen(d.label) + 1];
        strcpy(label, d.label);
}
                cout << “derived copy constructor/n”;
        }
        // destructor
        ~Derived( )          
        {
                delete [ ] label; 
                cout << “derived destructor/n”;
        }
        const Derived& operator= (const Derived& d);
friend ostream& operator << (ostream&, const Derived&);
};

const Derived& Derived:perator= (const Derived& d)
{
        if (this != &d)
        {
                delete [ ] label;
                Base:perator=(d);        //  Assign the Base part of d
to the Base
// part of the object that calls this operator;
f = d.f;
if (!d.label) { label = NULL; }
else
{
        label = new char [strlen(d.label) + 1];
                        strcpy(label, d.label);
                }
                cout << “derived assignment operator/n”;
        }
        return *this;
}

ostream& operator << (ostream& out, const Derived& d)
{
        out << (Base)d;                // Convert d to Base object
to output Base members.
        out << “Derived member f = ” << d.f << endl;
        out << “Derived member label = ” << d.label <<
endl;
        return out;
}

int main( )
{
        Derived d1;
Derived  d2(d1);

        return 0;
}

 

2 向量的数量积,又叫:点乘

题   目:      多态性和虚函数        

};

3 向量的向量积,又叫:叉乘

                                              

//fraction 类成员函数的实现

4 向量单位化(normalization)

班   级:                   

fraction::fraction(int aa ,int bb ):a(aa),b(bb)
{
    //a
= aa;
    //b = bb;
}

 

学   号:                

fraction::fraction()
{
    a = 0;
    b = 1;
}

[cpp] 

姓   名:                     

fraction::~fraction()
{

//Vecotr3.h  

 

}

#pragma once  

 

int fraction::getab(int aa,int bb)
{
    a = aa;
    b = bb;
    return 0;
}

  

 

void const fraction::show()
永利官网ylg客户端,{
    cout<<“(“<<a<<“/”<<b<<“)”;
}

extern const double uZero;  

  

const fraction & fraction::operator=(const fraction &f)
{
    a = f.a;
    b = f.b;
    return *this;

  

   

}

class Vector3  

   

//////////////////////////////////////////////////////////////////////
//运算符重载

{  

   

const fraction operator+(const fraction &f1,const fraction &f2)
{
    fraction fra;
    fra.a = (f1.a*f2.b + f1.b*f2.a);
    fra.b = (f1.b*f2.b);
    return fra;
}

    float x, y, z;  

评语:

const fraction operator-(const fraction &f1,const fraction &f2)
{
    fraction fra;
    fra.a = (f1.a*f2.b – f1.b*f2.a);
    fra.b = (f1.a*f2.b);
    return fra;
}

public:  

   

const fraction operator*(const fraction &f1,const fraction &f2)
{
    fraction fra;
    fra.a = (f1.a*f2.a);
    fra.b = (f1.a*f2.b);
    return fra;
}

    Vector3():x(0), y(0), z(0){}  

 

const fraction operator/(const fraction &f1,const fraction &f2)
{
    fraction fra;
    fra.a = (f1.a*f2.b);
    fra.b = (f1.b*f2.a);
    return fra;
}
////////////////////////////////////////////////////////////////

    Vector3(float x1, float y1, float z1):x(x1), y(y1), z(z1){}  

   

int main()
{
    fraction fen1(1,2);
    //fen1.show();
    //cout<<endl;

    Vector3(const Vector3 &v);  

 

    fraction fen2(5,6);
    //fen2.show();
    //cout<<endl;

    ~Vector3();  

   

    fraction fen3,fen4,fen5,fen6;
    
    fen3 = (fen1 + fen2);
    fen1.show();
    cout<< “+” ;
    fen2.show();
    cout<< ” =
” ;
    fen3.show();
    cout<< endl;

    void operator=(const Vector3 &v);  

 

    fen4 = (fen2 – fen1);
    fen1.show();
    cout<< “-” ;
    fen2.show();
    cout<< ” =
” ;
    fen4.show();
    cout<< endl;

    Vector3 operator+(const Vector3 &v);  

   

    fen5 = (fen2 * fen1);
    fen1.show();
    cout<< “*”
;
    fen2.show();
    cout<< ” =
” ;
    fen5.show();
    cout<< endl;

    Vector3 operator-(const Vector3 &v);  

 

    fen6 = (fen1 / fen2);
    fen1.show();
    cout<< ” /
” ;
    fen2.show();
    cout<< ” =
” ;
    fen6.show();
    cout<< endl;

    Vector3 operator/(const Vector3 &v);  

   

    return 0;
}

    Vector3 operator*(const Vector3 &v);  

 

    Vector3 operator+(float f);  

   

    Vector3 operator-(float f);  

 

    Vector3 operator/(float f);  

   

    Vector3 operator*(float f);  

成绩:                   
        指导教师:                  

    float dot(const Vector3 &v);  

   

    float length();  

 

    void normalize();  

   

    Vector3 crossProduct(const Vector3 &v);  

                             批阅时间:    年    月     日

    void printVec3();  

   

};  

   

[cpp]  

  

//Vector3.cpp  

 

#include”Plane.h”  

 

#include<iostream>  

ylg娱乐官网, 

  

 

const double uZero = 1e-6;  

 

  

 

//复制构造函数,必须为常量引用参数,否则编译不通过  

 

Vector3::Vector3(const Vector3 &v):x(v.x), y(v.y), z(v.z)  

 

{  

 

}  

 

  

 

Vector3::~Vector3()  

 

{  

  1. 实验内容或题目

}  

(1)声明二维坐标类作为基类派生圆的
类,把派生类圆作为基类,派生圆柱体类。其中,基类二维坐标类有成员数据:x、y坐标值;有成员函数:构造函数实现对基类成员数据的初始化、输出的成员函数,要求输出坐标位置。派生类圆类有新增成员数据:半径(R);有成员函数:构造函数实现对成员数据的初始化、计算圆面积的成员函数、输出半径的成员函数。派生圆柱体类新增数据有高(H);新增成员函数有构造函数、计算圆柱体体积的函数和输出所有成员的函数。请完成程序代码的编写、调试。

  

(2)教材393页7-8题。

void Vector3::operator=(const Vector3 &v)  

(3)教材416页1、4、5题。

{  

  1. 实验目的与要求

    x = v.x;  

(1)理解继承与派生的概念

    y = v.y;  

(2)掌握通过继承派生出一个新的类的方法

    z = v.z;  

(3)了解多态性的概念

}  

(4)了解虚函数的作用与使用方法

  

⑵ 源代码

Vector3 Vector3::operator+(const Vector3 &v)  

(1)#include<iostream>

{  

using namespace std;

    return Vector3(x+v.x, y+v.y, z+v.z);  

class point 

}  

{ public: 

  

point(float a=0,float b=0);

Vector3 Vector3::operator-(const Vector3 &v)  

void setpoint(float,float); 

{  

float get_x()const{return x;} 

    return Vector3(x-v.x, y-v.y, z-v.z);  

float get_y()const{return y;} 

}  

friend ostream &operator<<(ostream &,  point &);

  

protected:  float x,y;

Vector3 Vector3::operator/(const Vector3 &v)  

};

{  

point::point(float a,float b)

    if (fabsf(v.x) <= uZero || fabsf(v.y) <= uZero || fabsf(v.z)
<= uZero)  

{  x=a;

    {  

   y=b;

        std::cerr<<“Over flow!n”;  

}

        return *this;  

void point::setpoint(float a,float b)

    }  

{  x=a; 

    return Vector3(x/v.x, y/v.y, z/v.z);  

   y=b;

}  

}

  

ostream &operator<<(ostream &output,const point&p)

Vector3 Vector3::operator*(const Vector3 &v)  

{  

   
output<<“[“<<p.get_x()<<“,”<<p.get_y()<<“]”<<endl; 

    return Vector3(x*v.x, y*v.y, z*v.z);  

    return output;

}  

}

  

class circle:public point

Vector3 Vector3::operator+(float f)  

{ public: 

{  

circle(float a=0,float b=0,float r=0):point(a,b),radius(r){} 

    return Vector3(x+f, y+f, z+f);  

float area()const{return 3.14*radius*radius;}  

}  

float getradius()const{return radius;}

  

protected:  float radius; };

Vector3 Vector3::operator-(float f)  

class cyl:public circle

{  

{ public: 

发表评论

电子邮件地址不会被公开。 必填项已用*标注