C++note

//求公倍数和公约数的例子:
#include "stdio.h"
#include <conio.h>

void main()
{
 int a,b,i,minnum,maxnum;
 printf("请输入a,b的值:");
 scanf("%d%d",&a,&b);
 i=a>b?a:b;
 for(;i<=a*b;i++)
  if ((i%a==0)&&(i%b==0))
  {minnum=i;
  break;}
 for(i=a;i>=1;i--)
  if ((a%i==0)&&(b%i==0))
  {maxnum=i;
  break;}
 printf("最小公倍数是:%d/n",minnum);
 printf("最大公约数是:%d/n",maxnum);
 getch();
}


//冒泡法排序的例子
#include <iostream>
using namespace std;

void main()
{
 int i,j,num[10],temp;
 printf("请输入10个数,并以空格结束:");
 for(i=0;i<=9;i++)
  scanf("%d",&num[i]);
 printf("original:/n");
 for(i=0;i<=9;i++)
  printf("%d/n",num[i]);

 for(i=0;i<9;i++)
 {
  for(j=0;j<9-i;j++)
   if (num[j]>num[j+1])
   {
    temp=num[j];
    num[j]=num[j+1];
    num[j+1]=temp;
   }
 }

 printf("冒泡法:/n");
 for(i=0;i<=9;i++)
  printf("%d/n",num[i]);
}


//选择法排序的例子:
#include <conio.h>
#include <stdio.h>

void main()
{
    int num[10];
    int i,j,p ;
    int temp ;
   
 printf("请输入10个数,并以空格结束:");
    for(i=0;i<=9;i++)
    scanf("%d",&num[i]);
    printf("orignal:/n");
    for(i=0;i<=9;i++)
    printf("%d/n",num[i]);
   
    for(i=0;i<9;i++)
    {
        p=i;
        for(j=i+1;j<=9;j++)
        {
            if(num[p]>num[j])
   {p=j;
       
       temp=num[i];
                num[i]=num[p];
                num[p]=temp ;
            }
        }
    }
   
    printf("select sort:/n");
    for(i=0;i<=9;i++)
    printf("%d/n",num[i]);
    getch();
}


//文件包含
#include "file.h"和#include <file.h>都是合法的。二者的区别是用尖括号(<file.h>)形式时,系统到存放到c库函数头文件所在的目录中寻找要包含的文件,这称为标准方式。用双引号("file.h")形式时,系统先在用户当前目录中寻找要包含的文件,若找不到,再按标准方式查找。


//const限定修饰符
#include <iostream>
using namespace std;

void main()
{
 const int a=3;//const int a=3与int const a=3等效.
 const int *p; //p是一个指向int类型的const对象的指针.
 p=&a;
}

void main()
{
 int a;
 const int *p;
 p=&a;//这样也是正确的.
}

指针常量int * const p=&a;必须在定义时初始化.


//引用类型
int a=3;
int &refa=a;//引用在定义时必须进行初始化.引用就是变量的别名.
//对指针的引用:
int a=5;
int *p=&a;
int * &refp=p;
//const 引用可以用不同类型的对象初始化只要能从一种类型转换到另一种类型即可
也可以是不可寻址的值如文字常量例如
double dval = 3.14159;
//仅对于const 引用才是合法的
const int &ir = 1024;
const int &ir2 = dval;
const double &dr = dval + 1.0;
//枚举类型
枚举enumeration 提供了一种替代的方法它不但定义了整数常量而且还把它们组
成一个集合例如
enum open_modes{ input = 1, output, append };
//数组类型
数组名相当于常量指针,如int a[10];a即等价于&a[0];
a[2][3];a+1等价于a[1]的地址
//容器类型
数组习惯
STL习惯:vector <int> text;text.push_back(3);
//复数 #include <complex>
//typedef int integer; integer a=3;
//volatile 限定修饰符
当一个对象的值可能会在编译器的控制或监测之外被改变时例如一个被系统时钟更新的变量那么该对象应该声明成volatile.
//pair类型 #include <utility>


//函数中调换2个数
void change(int *pa,int *pb)
{
 int temp;
 temp=*pa;
 *pa=*pb;
 *pb=temp;
}

void main()
{
 int a=5,b=3;
 int *pa,*pb;
 pa=&a;
 pb=&b;
 change(pa,pb);
 printf("a=%d,b=%d/n",a,b);
}


//inline函数(内联函数)
调用频率高,代码段不是很长
编译时,在调用处内部展开
类定义的时候,所定义的成员函数也是内联函数

//函数重载
在同一作用域当中,能允许有多个同名函数存在
//构造函数和析构函数


//域和生命期
域:在c++中,每个名字都有一个唯一的实体(对象、函数、类、模版)
c++中有三种域,局部域、名字空间域、类域
名字解析:将表达式中的一个名字与某一个声明相关联的过程。
局部域名字解析:
extern 扩展作用域,生命期相同
有三种局部对象自动对象:automatic object 寄存器对象,register object 以及局部静态对象local static object
//名字空间****


//类
一个简单的例子
#include <iostream>
using namespace std;

class sample
{
private:
 int x,y;
public:
 void SetValue(int a,int b)
 {
  x=a;
  y=b;
 };
 void Print()
 {
  cout<<x<<endl;
  cout<<y<<endl;
 };
};

void main()
{
 sample sample1;
 sample1.SetValue(3,5);
 sample1.Print();
}
类的public里面可以定义变量,但不能赋初值;类里面的变量都不能赋初值,因为类定义的时候并没有分配存储空间.


//构造函数
用来初始化对象,每个对象实例化的时候都会调用构造函数,本身有一个默认的构造函数。构造函数名跟类名相同,函数体无内容。在一个类当中,可以有多个构造函数。
eg1.
class sample
{
private:
 int x,y;
public:
 sample();
 sample(int a,int b)
 {x=a;y=b;};
};
};

eg2.
#include <iostream>
using namespace std;

class sample
{
private:
 int x,y;
public:
 sample(int a,int b);
 void printAll()
 {
  cout<<"x="<<x<<",y="<<y<<endl;
 }
};

sample::sample(int a,int b)
{

 x=a;
 y=b;
}

void main()
{
 sample c(4,8);
 c.printAll();
}

eg3.
class sample
{
private:
 int x,y;
public:
 sample(int a,int b=1)
 {
  x=a;
  y=b;
 };
 void printAll()
 {
  cout<<"x="<<x<<",y="<<y<<endl;
 }
};

void main()
{
 sample c(4);  //y=1;
 sample d(4,5); //y=5;前面的一个参数不能作为常量
 c.printAll();
 d.printAll();}

eg4:一个例子来判断3个点是否能构成三角形,如果能就求其面积
#include <iostream>
#include <math.h>
using namespace std;

class cPoint
{
public:
 float x,y;      //因为要直接访问x、y,所以就不把它们定义在private区了
 cPoint(float a,float b)  //构造函数
 {
  x=a;
  y=b;
 }
};

float s(cPoint a,cPoint b)  //求边长
{
 float bian;
 bian=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 cout<<"边长:"<<bian<<endl;
 return bian;
}

void mj(float s1,float s2,float s3)  //判断是否能构成三角形,如果能则求其面积
{
 float s;
 float mianji;
 if (((s1+s2)>s3)&&((s1+s3)>s2)&&((s2+s3)>s1))
 {
  cout<<"这三个点可以构成三角形,并且这个三角形的面积是:";
  s=(s1+s2+s3)/2;
  mianji=sqrt(s*(s-s1)*(s-s2)*(s-s3));
  cout<<mianji;
 }
 else
  cout<<"这三个点不能构成三角形";
}

void main()
{
 float x1,y1,x2,y2,x3,y3;
 float s1,s2,s3; //3条边的长度
 cin>>x1>>y1>>x2>>y2>>x3>>y3;
 cPoint p1(x1,y1),p2(x2,y2),p3(x3,y3);  //实例化p1、p2、p3
 s1=s(p1,p2);  //调用s函数求边长
 s2=s(p2,p3);
 s3=s(p1,p3);
 mj(s1,s2,s3);  //调用mj函数
}
//析构函数
当对象销毁时,自动调用,函数前有~

//友元函数
定义友元函数加friend关键字
友元函数的特点:
1、除了有权访问私有变量外,没有任何特殊之处
2、友元函数没有this指针
3、在类中声明不受位置影响,可以在私有变量中声明,也可以在公有变量中声明
4、友元函数的定义不需要加前缀类名及::符号
5、友元函数必须要在所访问的数据的所属的类中声明
eg1:利用友元函数求老师比学生的年龄大多少
#include <iostream>
using namespace std;

class teacher;
class student
{
private:
 int st_age;
public:
 friend void display(student a,teacher b);
};

class teacher
{
private:
 int te_age;
public:
 friend void display(student a,teacher b);
};

void display(student a,teacher b) //用到多个类的时候必须在外面写
{
 a.st_age=20;
 b.te_age=23;
 cout<<b.te_age-a.st_age<<endl;
}

void main()
{
 student stu;
 teacher tea;
 display(stu,tea);
}


eg2:利用友元函数求圆和矩形的面积
#include <iostream>
using namespace std;

class rectangle;
class circle
{
private:
 float r;
 float area;
public:
 circle(float a)
 {
  r=a;
 };
 
 void jsarea()
 {
  area=3.14*r*r;
 };
 friend void display(circle a,rectangle b);
};

class rectangle
{
private:
 float length;
 float width;
 float area;
public:
 rectangle(float i,float j)
 {
  length=i;
  width=j;
 };
 void jsarea()
 {
  area=length*width;
 };
 friend void display(circle a,rectangle b);
};

void display(circle a,rectangle b)
{
 a.jsarea();
 b.jsarea();
 cout<<"园的面积:"<<a.area<<endl;
 cout<<"矩形的面积:"<<b.area<<endl;
}

void main()
{
 circle circle1(3);
 rectangle rectangle1(3,4);
 display(circle1,rectangle1);
}

eg3:在一个类中是成员函数,另一个类中是友元函数的例子
#include <iostream>
using namespace std;

class beta;
class alpha
{
private:
 int a_data;
public:
 alpha()
 {
  a_data=10;
 };
 void display(beta);
};

class beta
{
private:
 int b_data;
public:
 beta()
 {
  b_data=20;
 };
 friend void alpha::display(beta bb);
};

void alpha::display(beta bb)
{
 cout<<"indateofbeta="<<bb.b_data<<endl;
 cout<<"indateofalpha="<<a_data;
}

void main()
{
 alpha a1;
 beta b1;
 a1.display(b1);
}


//友元类
eg1:
#include <iostream>
using namespace std;

class beta;
class alpha
{
private:
 int data;
public:
 alpha()
 {
  data=10;
 };
 friend class beta;
};

class beta
{
public:
 void display(alpha d)
 {
  cout<<d.data<<endl;
 };
 void get_data(alpha d)
 {
  int x=d.data;
  cout<<x<<endl;
 };
};

void main()
{
 alpha a;
 beta b;
 b.display(a);
 b.get_data(a);
}


//运算符的重载   关键字operator
将现有的运算符与成员函数相关联,并且与其类对象一起用作其操作数,这种能力被称为运算符重载。
eg1:二元运算符重载
#include <iostream.h>
#include <string.h>

const size=80;
class phrase
{
private:
 char str[size];
public:
 phrase()
 {
  strcpy(str,"");
 };
 phrase(char *s)
 {
  strcpy(str,s);
 };
 void display()
 {
  cout<<str<<endl;
 };
 phrase operator+=(phrase aa)
 {
  if ((strlen(str)+strlen(aa.str))<size)
  {
   strcat(str,aa.str);
   return (*this);
  }
  else
  {
   cout<<"string is too long";
   return (*this);
  }
 };
};

void main()
{
 phrase s1;
 phrase s2("check the program");
 s1+=s2;
 s1.display();
 s1="next ";
 phrase s3;
 s3=s1+=s2;
 s3.display();
 phrase s4;
 phrase s5(" and again");
 s4=s2+=s5+=s5;
 s4.display();
}
//运行结果
check the program
next check the program
check the program and again and again

eg2:一元运算符的重载,运行结果是1s
#include <iostream>
using  namespace std;

class sample
{
private:
 int counter;
public:
   sample()
   {counter=0;
   }
  sample operator++()
  {  sample t;
       t.counter=++counter;
       return t;
   }
 

   void display()
   { cout<<counter<<endl;
   }
};

void main()
{
   sample obj1, obj2;
  
   obj2=++obj1;
   obj2.display();
};

//this指针例子
#include <iostream>
using namespace std;

class A
{
public:
 A(int i,int j)
 {
  a=i;b=j;
 }
 A()
 {
  a=b=0;
 }
 void copy(A &aa);
 int returna()
 {
  return a;
 }
 int returnb()
 {
  return b;
 }
private:
 int a,b;
};

void A::copy(A &aa)
{
 if (this==&aa)
  return;
 *this=aa;
}

void main()
{
 A a1,a2(3,4);
 a1.copy(a2);
 cout<<a1.returna()-a2.returna()<<",";
 cout<<a1.returnb()+a2.returnb()<<endl;
}


//类里面定义静态变量的例子
#include <iostream>
using namespace std;
class myclass
{
private:
 int a,b,c;
 static int sum;
public:
 myclass(int a,int b,int c);
 void getnumber();
 int getsum(myclass m);
};

int myclass::sum=0; //int myclass::sum(0);相同效果

myclass::myclass(int d,int e,int f)
  {
   a=d;b=e;c=f;
   sum+=a+b+c;
  }

void myclass::getnumber()
{
 cout<<a<<";"<<b<<";"<<c<<endl;
}

int myclass::getsum(myclass m)
{
 return myclass::sum;
}

void main()
{
 myclass m(3,4,5),n(5,6,7);
 n.getnumber();
 cout<<m.getsum(m)<<";";
 cout<<m.getsum(n)<<endl;
}


//静态成员函数
#include <iostream.h>

class M
{
private:
 int A;
 static B;
public:
 M(int a)
 {
  A=a;B+=a;
 }
 static void fun(M m);
};

void M::fun(M m)
{
 cout<<"A="<<m.A<<endl;
 cout<<"B="<<B<<endl; //写成m.B或M::B都可以
}

int M::B=10;

void main()
{
 M P(6),Q(8);
 M::fun(P);  //写成P.fun(P)也可以
 Q.fun(Q);
}


//类、抽象、对象、继承、封装、多态
1、对象:是定义了边界,与要解决的问题有关的概念和事物,即类的实例化
2、类:拥有相同的特性,共同的行为和共同的关系的一组对象,即对对象的抽象
3、数据抽象:将与特定实体有关的特性和方法与应用程序相关的过程
4、继承:是允许通过重用现有类来构建新类的特性
5、封装:是让你有选择地隐藏类中的特性和方法的过程
6、多态:使同一函数在不同的类上具有不同的行为
7、继承:继承分为单继承和多继承


//单继承
#include <iostream>
using namespace std;

class employee
{
private:
 int priva;
protected:
 int prota;
public:
 int puba;
};

class manager:public employee
{
public:
 void fn()
 {
  int a;
  a=priva; //错误,不能被继承
  a=prota; //对,继承下来变成private了
  a=puba;  //对
 }
};

class clerk:private employee
{
public:
 void cl()
 {
  int a;
  a=priva;//wrong
  a=prota;//write
  a=puba;//write
 }
};

void main()
{
employee emp;
emp.priva=1; //错
emp.prota=1; //错
emp.puba=1; //对
manager man;
man.priva=1; //错
man.prota=1; //错 
man.puba=1; //对
clerk cle;
cle.priva=1;//wrong
cle.prota=1;//wrong
cle.puba=1;//wrong
}
在派生类的类声明中(class B:public A),关键字public指定派生类的对象能访问基类的"public"成员.
而使用private,main()中派生类的对象则不能访问基类的public数据成员(此种情况基类的private不能被派生类继承,protected继承下来之后变成private,publci继承下来也变成private),类外的对象决不能访问类的private和protected数据成员
使用protected,基类中的private不被继承,protected继承下来还是protected,public继承下来也是protected


#include <iostream.h>
#include <conio.h>

class vehicle
{
protected:
 int wheels;
 double weight;
public:
 void initialise(int whls,double wght);
 int get_wheels()
 {
  return wheels;
 }
 double get_weight()
 {
  return weight;
 }
 double wheel_loading()
 {
  return (weight/wheels);
 }
};

class car:public vehicle
{
private:
 int passenger_load;
public:
 void initialise(int whls,double wght,int people=4);
 int passengers()
 {
  return passenger_load;
 }
};

class truck:public vehicle
{
private:
 int passenger_load;
 double payload;
public:
 void init_truck(int number=2,double max_load=24000.0);
 double efficiency();
 int passengers()
 {
  return passenger_load;
 }
};

void vehicle::initialise(int whls,double wght)
{
 wheels=whls;
 weight=wght;
}

void car::initialise(int whls,double wght,int people)
{
 passenger_load=people;
 wheels=whls;
 weight=wght;
}

void truck::init_truck(int number,double max_load)
{
 passenger_load=number;
 payload=max_load;
}

double truck::efficiency()
{
 return payload/(payload+weight);
}

void main()
{
 //clrscr();
 vehicle bicycle;
 bicycle.initialise(2,25);
 cout<<"The bicycle has "<<bicycle.get_wheels()<<" wheels./n";
 cout<<"The bicycle weights "<<bicycle.get_weight()<<" pounds./n/n";
 car coupe;
 coupe.initialise(4,3500,5);
 cout<<"The coupe carries "<<coupe.passengers()<<" passengers./n";
 cout<<"The coupe weights "<<coupe.get_weight()<<" pounds./n";
 cout<<"The coupe wheel loading is "<<coupe.wheel_loading()<<" pounds per tire./n/n";
 truck van;
 van.initialise(18,12500.0);
 van.init_truck(1,33675.0);
 cout<<"The van weighs "<<van.get_weight()<<" pounds./n";
 cout<<"The van's efficiency is "<<100.0*van.efficiency()<<" percent./n";
}
//派生类中的构造函数和析构函数
派生类中,构造函数是先调用基类中的构造函数,再执行自己的构造函数
析构的顺序相反
下面的例子中如果不加:Base()也可以,那就不会调用基类中的构造函数了
eg1:#include <iostream>
using namespace std;

class Base
{
protected:
 int a;
public:
 Base()
 {
  a=0;
 }
 Base(int c)
 {
  a=c;
 }
};

class Derived:public Base
{
public:
 Derived():Base()
 {
 }
 Derived(int c):Base(c)
 {}
};

void main()
{
 Derived obj1;
 Derived obj2(20);
}

eg2:
#include <iostream.h>
class A
{
private:
 int a;
public:
 A()
 {
  a=0;
  cout<<"Default constrct called A/n";
 }
 A(int i)
 {
  a=i;
  cout<<"Constructor called A/n";
 }
 ~A()
 {
  cout<<"Destructor called A/n";
 }
 void print()
 {
  cout<<a<<",";
 }
 int geta()
 {
  return a;
 }
};

class B:public A
{
private:
 int b;
 A aa;
public:
 B()
 {
  b=0;
  cout<<"Default constructor called B/n";
 }
 B(int i,int j,int k);
 ~B()
 {
  cout<<"Destructor called B/n";
 }
 void print()
 {
  A::print();
  cout<<b<<","<<aa.geta()<<endl;
 }
};

B::B(int i,int j,int k)
{
 cout<<"Constructor called B/n";
}

void main()
{
 B bb[2];
 bb[0]=B(3,4,5);
 bb[1]=B(7,-8,9);
 for(int i=0;i<2;i++)
  bb[i].print();
}

eg3://输出0,0,0;0,0,5;1,2,3
#include <iostream>
using namespace std;

class A
{
private:
 int a;
public:
 A()
 {a=0;}
 A(int i)
 {a=i;}
 void print ()
 {
  cout<<a<<",";}
};

class B:public A
{
private:
 int b1,b2;
public:
 B()
 {b1=b2=0;}
 B(int i)
 {b1=0;b2=i;}
 B(int i,int j,int k):A(i),b1(j),b2(k)
 {}
 void print()
 {
  A::print();
  cout<<b1<<","<<b2<<endl;
 }
};

void main()
{
 B b1;
 B b2(5);
 B b3(1,2,3):A(1),b1(2),b2(3)
 b1.print();
 b2.print();
 b3.print();
}


//派生类中调用成员函数
class base
{
protected:
 int ss;
public:
 int func()
 {return ss;}
};

class derived:public base
{
public:
 int func()
 {
  return base::func();
 }
};

void main()
{
 base b1;
 b1.func();
 derived a1;
 a1.func();
}


//容器类
class engine:
{
private:
 int num;
public:
 engine(int s)
 {num=s;}
};

class jet
{
private:
 int jt;
 engine eobj;
public:
 jet(int x,int y):eobj(y)
 {jt=x;}
};


//多重继承
class Teacher
{
private:
.......
};
class Student
{
private:
.......
};

class TS:public Teacher,public Student
{
.....
};
二义性,如果两个基类中都有同名的成员函数,派生类调用的时候会引起这个问题

//多重继承中的构造函数和析构函数
eg1:
输出结果:
constructing B22
constructing B11
constructing B3 *
constructing B13
constructing B24
constructing B3 *
destrcting B3
destrcuting B2
destructing B1
destrcting B3
destructing B1
destrcuting B2

#include <iostream.h>
class B1
{
public:
 B1(int i)
 {cout<<"constructing B1"<<i<<endl;}

 ~B1()
 {cout<<"destructing B1"<<endl;}
};

class B2
{
 public:
  B2(int j)
  {cout<<"constructing B2"<<j<<endl;}
  ~B2()
  {cout<<"destructing B2"<<endl;}
};

class B3
{
public:
  B3()
  {cout<<"constructing B3 *"<<endl;}
  ~B3()
  {cout<<"destructing B3"<<endl;}
};

class C:public B2,public B1,public B3
{
public:
  C(int a,int b,int c,int d):B1(a),memberB2(d),memberB1(c),B2(b)
  {}
private:
  B1 memberB1;
  B2 memberB2;
  B3 memberB3;
};

void main()
{
  C obj(1,2,3,4);
}

eg2:
输出结果:
constructor A17
constructor A26
constructor A38
constructor D9
7
6
9,8
constructor A24
6
constructor A12
7

#include <iostream.h>

class A1
{
private:
 int a1;
public:
 A1(int i)
 {
  a1=i;
  cout<<"constructor A1"<<a1<<endl;
 }
 void print()
 {
  cout<<a1<<endl;
 }
};

class A2
{
private:
 int a2;
public:
 A2(int j)
 {
  a2=j;
  cout<<"constructor A2"<<a2<<endl;
 }
 void print()
 {
  cout<<a2<<endl;
 }
};

class A3
{
private:
 int a3;
public:
 A3(int k)
 {
  a3=k;
  cout<<"constructor A3"<<a3<<endl;
 }
 int geta3()
 {
  return a3;
 }
};

class D:public A1,public A2
{
private:
 int d;
 A3 a3;
public:
 D(int i,int j,int k,int l):A2(i),A1(j),a3(k)
 {
  d=l;
  cout<<"constructor D"<<d<<endl;
 }
 void print()
 {
  A1::print();
  A2::print();
  cout<<d<<","<<a3.geta3()<<endl;
 }
};

void main()
{
 D dd(6,7,8,9);
 dd.print();
 A2 a2(4);
 a2=dd;
 a2.print();
 A1 a1(2);
 a1=dd;
 a1.print();
}

多继承的缺陷在于
例:一个类向下分支成2个类,然后再合并,用虚基类可以解决
class B1:virtual public A
{};
class B2:virtual public A
{};
class C:public B1,public B2
{};


//虚函数及动态联编
eg1://运行结果137.5
#include <iostream.h>

class Point
{
private:
 double x,y;
public:
 Point(double i,double j)
 {x=i,y=j;}
 virtual double Area()const  //const在此的目的是防止改变类中私有变量
 {return 0.0;}
};

class Rectangle:public Point
{
private:
 double w,h;
public:
 Rectangle(double i,double j,double k,double l);
 virtual double Area()const   //加virtual后基类继承过来后保留派生类,如果不加,则此派生类中有2个同名的成员函数
 {return w*h;}
};

Rectangle::Rectangle(double i,double j,double k,double l):Point(i,j)
{w=k;h=l;}

void fun(Point &s)
{cout<<s.Area()<<endl;}

void main()
{
 Rectangle rec(3.4,15.2,5.0,27.5);
 fun(rec);
}

eg2:上例改编后的
#include <iostream.h>

class Shape
{
private:
 double x,y;
public:
 Shape()
 {}
 virtual double Area()const
 {return 0.0;}
};

class Rectangle:public Shape
{
private:
 double w,h;
public:
 Rectangle(double k,double l)
 {w=k;h=l;}
 virtual double Area()const
 {return w*h;}
};

class Circle:public Shape
{
private:
 double r;
public:
 Circle(double i)
 {r=i;}
 virtual double Area()const
 {return 3.14*r*r;}
};

void fun(Shape *s)
{cout<<(*s).Area()<<endl;} //与s->Area()等价

void main()
{
 Rectangle *rec=new Rectangle(10,10);
 fun(rec);
 Circle *cir=new Circle(10);
 fun(cir);
}


//纯虚函数及抽象类
纯虚函数是一种没有具体实现的虚函数

eg1:
#include <iostream>
using namespace std;

class point
{
private:
 int x0,y0;
public:
 point(int i=0,int j=0)
 {x0=i,y0=j;}
 virtual void draw()=0;
};

class line:public point
{
private:
 int x1,y1;
public:
 line(int i=0,int j=0,int m=0,int n=0):point(i,j)
 {x1=m,y1=n;}
 void draw()
 {cout<<"line::draw() called /n";}
};

class ellipse:public point
{
private:
 int x2,y2;
public:
 ellipse(int i=0,int j=0,int p=0,int q=0):point(i,j)
 {x2=p,y2=q;}
 void draw()
 {cout<<"ellispe::draw() called /n";}
};

void drawobj(point *p)
{p->draw();};

void main()
{
 line *lineobj=new line;
 ellipse *ellipseobj=new ellipse;
 drawobj(lineobj);
 drawobj(ellipseobj);
}

eg2://此例也包括指向指针的指针,运行结果Area's Sum=380.713
#include <iostream.h>
const double PI=3.1415;
class Shap
{
public:
 virtual double Area() const=0;
};

class Triangle:public Shap
{
private:
 double H,W;
public:
 Triangle(double h,double w)
 {
  H=h;W=w;}
 double Area() const
 {return 0.5*H*W;}
};

class Rectangle:public Shap
{
private:
 double H,W;
public:
 Rectangle(double h,double w)
 {H=h;W=w;}
 double Area() const
 {return H*W;}
};

class Circle:public Shap
{
private:
 double R;
public:
 Circle(double r)
 {R=r;}
 double Area() const
 {return PI*R*R;}
};

class Trapezoid:public Shap
{
private:
 double T,B,H;
public:
 Trapezoid(double t,double b,double h)
 {T=t;B=b;H=h;}
 double Area() const
 {return 0.5*(T+B)*H;}
};

class Square:public Shap
{
private:
 double S;
public:
 Square(double s)
 {S=s;}
 double Area() const
 {return S*S;}
};

class Application
{
public:
 double Compute(Shap *s[],int n) const;
};

double Application::Compute(Shap *s[],int n) const
{
 double sum=0;
 for(int i=0;i<n;i++)
  sum+=s[i]->Area();
 return sum;
}

class MyProgram:public Application
{
private:
 Shap **s;
public:
 MyProgram();
 ~MyProgram();
 double Run();
};

MyProgram::MyProgram()
{
 s=new Shap *[5];
 s[0]=new Triangle(3.0,5.0);
 s[1]=new Rectangle(5.0,8.0);
 s[2]=new Circle(8.5);
 s[3]=new Trapezoid(12.0,8.0,6.0);
 s[4]=new Square(6.8);
}

MyProgram::~MyProgram()
{
 for(int i=0;i<5;i++)
  delete s[i];
 delete[] s;
}

double MyProgram::Run()
{
 double sum=Compute(s,5);
 return sum;
}

void main()
{
 MyProgram M;
 cout<<"Area's Sum="<<M.Run()<<endl;
}


//函数模板  关键字template
int add(int a,int b)
{return (a+b);}
float add(float a,float b)
{return (a+b);}
1、定义
template <参数化类型名表> <返回类型名> <函数名> (<参数表>)
{//<函数体>}
参数化类型名表可以是内置数据类型,也可以是类类型,如果是类类型,要加上class关键字
函数模板在内存中并不分配存储空间
template <T>
T add(T a,T b)
{return (a+b);}

eg1:
#include <iostream>
using namespace std;

template <class T>
T min(T a,T b)
{return a<b?a:b;}

void main()
{
int x1=5,y1=8;
double x2=5.76,y2=5.77;
char x3='m',y3='n';
cout<<"min(x1,y1)="<<min(x1,y1)<<endl;
cout<<"min(x2,y2)="<<min(x2,y2)<<endl;
cout<<"min(x3,y3)="<<min(x3,y3)<<endl;
}

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

template <class stype> void bubble(stype *item,int count);

void main()
{
 char str[]="gtyfsarcb";
 bubble(str,(int)strlen(str));
 cout<<"The sorted string is:"<<str<<endl;
 int nums[]={9,4,2,6,8,5,1};
 bubble(nums,7);
 cout<<"The sorted numbers are:";
 for(int i=0;i<7;i++)
  cout<<nums[i]<<" ";
 cout<<endl;
}

template <class stype>
void bubble(stype *item,int count)
{
 register int i,j;
 stype t;
 for(i=1;i<count;i++)
  for(j=count-1;j>=i;j--)
  {
   if(item[j-1]>item[j])
   {
    t=item[j-1];
    item[j-1]=item[j];
    item[j]=t;
   }
  }
}


//类模板
运行结果:
integer array:1 2 3 4 5 6 7 8 9 10
double array:3.14 6.28 9.42 12.56 15.7

Index value of 20 is out-of-bounds.

#include <iostream.h>
#include<stdlib.h>
template <class AType>
class array
{
 private:
  int length;
  AType *a;
 public:
  array(int size);
  ~array()
  {delete[] a;}
  AType & operator[](int i);
};

template <class AType>
array <AType>::array(int size)
{
  register int i;
  length=size;
  a=new AType[size];
  if(!a)
  {cout<<"cannot allocate array./n";
     exit(1);
  }
  for(i=0;i<size;i++)
   a[i]=0;
}

template<class AType>
AType&array<AType>::operator[](int i)
  {
   if(i<0||i>length-1)
   {
    cout<<"/nIndex value of ";
       cout<<i<<" is out-of-bounds./n";
       exit(1);
   }
   return  a[i];
  }
  void main()
  {
   array <int> intob(10);
   array <double> doubleob(5);

   cout<<"integer array:";
   for(int i=0;i<10;i++)
    intob[i]=i+1;
      for( i=0;i<10;i++)
    cout<<intob[i]<<" ";
   cout<<endl;

   cout<<"double array:";
   cout.precision(4);
   for(i=0;i<5;i++)
    doubleob[i]=(double)(i+1)*3.14;
   for(i=0;i<5;i++)
    cout<<doubleob[i]<<" ";
   cout<<endl;

   intob[20]=30;
   doubleob[20]=89.5;
  }


//考试中的
class integer
{
private:
 int value;
public:
 integer(int i=0)
 {value=0;}
 integer operator+(integer & other)//成员函数
 {
  integer temp;
  temp.value=value+other.value;
  return temp;
 }
};

改成友元函数为
friend integer operator +(integer other1,integer other2)
{
 integer temp;
 temp.value=other1.value+other2.value;
 return temp;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值