1 const 与volatile 的用法
1 const
#include<conio.h>
#include<iostream.h>
//行参数指向const 类型变量的指针
void display_c(cons int * pi)
{
cout<<"display_c:"<<*pi<<endl;
}
//行参为普通类型变量的指针
void display(int *pi)
{
cout<<"display_c:"<<*pi<<endl;
}
//const 类型变量
const int i1=1;
//error i1=3;
//const 类型变量的指针
int i2=2;
const int * pi2=&i2;
//error *pi2=3
// const 指针
int * const pi3=&i3;
*pi3=5;
// error *pi3=&i4 可以赋予不同的值,但是不可一指向不同的变量
//指向const 内容的const 指针
const int * cosnt pi5=&i5;
2 sizeof 返回某个便赖宁嘎或数据类型的长度
3 引用
1 引用变量
int i=1;
int & r_i=i;
5 名空间
1 namespace
namespace car
{
int model;
int length;
int width;
}
namespace plane
{
int model;
namespace size
{
int lenth;
int width;
}
}
namespace car //添加名空间的成员
{
char * name;
}
namespqce c=car; //定义别名
int Time //外不变量属于全局名空间
car::length=3;
plane::size::length=70;
int Time=1996;
::Time=1997;
2 using
void main()
{
using namespace car;
length;
using namespace phane;
model;
}
6 new 与delete 运算符
double * pd; // define pointer variable
pd=new double; // allocate memory
if(pd!=null)
{
...
delete pd; // free memory
}
double1=null
* pds=new double[100];
if(pds)
{
....
delete[] pds;
}
如果是使用new 进行内存空间分配没有成功,则返回空指针null
释放一个数组分配的内存是,常常采用带[]的形式
7 void 指针 它指向一个地址值,但是不说名数据类型,可以使用void 指针创建一个通用的函数,在使用
的时候将指针类型转化成相应的具体类型。
void ShowHex(void *pv,int siae)
{
....
((unsigned char *)pv)[i]
}
void main()
{
void *pv=null;
unsigned char c1=0x12;
pv=&c1;
ShowHex(pv,sizeof(c1));
}
9 typeid 运算符 用来求得变量或队形爱女嘎的数据类型,返回一个type_info 类型的对象,通过该对象
可以获取数据类型的名称
include<typeinfo.h>
int i;
const type_info &t0=typeid(i);
t0.name();
10 函数
1 模板函数
template<class T> T min(R &x,Tv&y)
{
return x<y?x:y;
}
2 指向函数的指针
int max(int x,int y)
{
...
}
int min(int x,int y)
{
...
}
int (* m_pfunction)(int,int);
void main()
{
m_pfunction=max;
(*m_pfunction)(2,3);
m_pfunction=min;
(*m_pfunction)(2,3);
}
11 类与对象
1 构在函数和析构函数
#include <iostream.h>
#include <string.h>
#include <conio.h>
class Book
{
private:
char * pBookName;
public:
int PageNum;
public:
Book(char * pBN=NULL);
~ B o o k ( v o i d ) ;
void SetBookName(char * pBN);
int GetBookName(char * pBN,unsigned int MaxSize);
} ;
Book:Book(char *PBN)
{
cout<<"构造函数"<<endl;
pBookName=null;
if(oBN!=null)
{
pBookName=new char[strlen(pBN)+1];
if(pBookName!=null)
strcyp(pBookName,pBN);
}
}
Book::~Book()
{
delete[] pBookName;
}
void Book::SetBookName(char * pBN)
{
if(pBookName!=null)
delete[] pBookName;
pBookName=new char[strlen(pBN)+1];
if(pBookName!=null)
strcyp(pBookName,pBN);
}
int Book::GetBookName(char * pBN,unsigned intmaxSize)
{
if((pBookName!=null))&&(MaxSize>strlen(pBookName))
{
strcpy(pBN,pBookName);
retrun strlen(strlen(pBookName));
}
}
// 使用
Book b1;
b1.SetBookName("test");
Book b2(test1);
2 对象的引用参数传递
void Add(Book b)
void AddRef(Book & b);
3 静态成员变量 是一个公共变量
在初始化 的时候利用作用运算符:: 对私有类型的静态成员变量可以向公有类型的静态成变量一样赋值
但不能直接引用
3 const 类型成员函数与mutable
class CDate
{
public:
int year;
mutable int month;
CDate(int y=2000,int m=1)
{
year=y;
month=m;
};
int BetMonth() const ;//read only
void SetMonth(int m);// write only
}
void CDate::SetMonth(int m)
{
month=m;
}
void main()
{
CDate d1;
}
在const 类型的成员函数定义中,不可一直接或简介的修改普通类型的成员变量
如果象修改const 类型对象的成员函数,可以使用关键字mutable 对该成员变量进行修改
5 对象的初始化与初始化行
将参数类表中的数值赋予成员变量时,不仅可以在构造函数的函数体中进行,以阿宽衣在初始化行中进行
在初始化处惊醒初始化的情况有:
1 分层类的构在函数可以调用它的任何一个子对象的构造函数
2 对常量const 类型的成员变量的初始化必须在初始化行上
3 对于引用类型的成员变量的初始化必须在初始化行上
class CPoint
{
public:
int x,y;
CPoint(int ax=0,int ay=0)
{
x=ax;
y=ay;
}
};
class CRect
{
private:
CPoint low_right;
CPoint up_left;
public:
int & CenterX;
const int CenterY;
CRect(int x1,int y1,int x2,int y2,int &x3,int y3)
:up_left(x1,y1),low_right(x2,y2),CenterX(x3),CenterY(y3)
{
}
};
void main()
{
int cx=5;
int cy=6;
CRect r1(1,2,3,4,cx,cy);
}
6 拷贝构造函数
拷贝构造函数与普通构造函数的差别在与棋参数类表,参数列表中有一个对象,该对象的数据类型是
本类的一个引用,而且一般情况下,该对象还应该是一个const 类型的对象。
如果在类的定义是不是显示的定义一个拷贝函数,则编译器会自动的定义一个拷贝构造函数
class CPoint
{
public:
int x,y;
CPoint(int m_x=0,ubt m_y=0); // default constructor
cPoint(const CPoint &c); //copy consrucotr
};
CPoint::CPoint(int m_x,int m_y)
{
}
CPoint::CPoint(const CPoint &c)
{
x=c.y;
y=c.x;
}
void main()
{
CPoint c1(1,2); //invoke default constructor
CPoint c2-c1; // invoke copy constructor
}
7 template class
template<class t,int Size>class Array // template class
{
private:
T arr[Size];
int CurSize;
public:
Array(T * date,int n)
{
CurSize=n<Size?n;Size;
for(int i=0;i<CurSize;i++)
{
Arr[i]=data[i];
}
}
}
void main()
{
int i1[10]={1,2,3,4,5,6,7,8,9};
Array<int,6>array_i1(i1,i0);
}
1 友员类和友员函数
#include <iostream.h>
#include<string.h>
#include<conio.h>
class SoftWareEngineer; //先对SoftwareEngineer 类进行显示说明一下
class Computer // 定义Computer 类
{
private:
int Price;
public:
Computer(int p){Price=p};
friend class SoftwareEngineer; //将友员类载这里声明
frined void Judge(Computer &c,SoftwareEngineer & s) //友员函数
};
class SoftwareEngineer
{
int Salary;
char Name[20];
public:
SoftwareEngineer(int s,char *n //构造函数)
{
Salary=s;
strcpy(Name,n);
}
int GetComputerPrice(Computer &c){return c.Price} //访问Computer 的思友变量
friend void Judge(Computer &c,SoftwareEngineer & s) //友员函数
};
//判断一个软件工程师是否可以用一个月的薪水买的器一台电脑
void Judge(Computer &c,SoftwareEngineer &s) //桥友员函数
{
if(c.Price>s.Salary)
cout<<"软件工程师"<<s.Name<<"的一个月薪水买不起一台电脑"<<endl;
else
cout<<"软件工程师"<<s.Name<<"的一月薪水买的起一台电脑"<<endl;
}
void main()
{
Computer c1(100);
SoftwareEngineer s1(120,"user1");
Judge(c1,s1);
SiftwareEngineer s2(80,"user2")
Judge(c1,s2);
getch();
}
2运算符重载
#include<iostream.h>
#include<conio.h>
#include<iomanip.h>
class TValue{
private:
int value;
public:
TValue(int i){value=i}
//成员函数重载运算符
TValue operator!();
TValue operator+(TValue & rv);
// 友员函数重载运算符
friend ostream & operator<<{ostream & os,TValue & rv};
}
TValue Tvalue::operator!()
{
return TValue(!value);
}
TValue TValue:operator+(TValue& rv)
{
return TValue(value+rv.value);
}
ostream & operator<<(ostream & os,TValue rv)
{
os<<setw(5)<<rv.value;
return os;
}
void main()
{
TValue v1(3),v2(5);
cout<<
}
3 类的派生和继承
1class Box{
public:
int width,height;
void SetWidth(int w){width=w};
void SetWidth(int h){height=h;};
};
class TColorBox::public Box{
public:
int color;
void SetColor(int c){color=c;};
};
void main(){
TColorBox cb;
cb.SetColor(255); //声明非继承类的对象
cb.SetWidth(100);//声明继承类的对象
cb.SetHeight(100); //声明继承类的对象
}
2 不能被继承的成员
构造函数,析构函数,用户定义的新操作符,用户定义的赋值操作,友员关系
3 构造函数,析构函数的调用顺序
class A{
int a,b,c;
public:
A(int x,int y,int z)
{
a=x;
b=y;
c=z;
}
};
class B{
int d;
public :
B(int xx):A(xx,xx+1,xx+2)(d=xx);//内联构造函数
B(int x,int y,int z,int xx);//非内联构造函数
B:B(int x,int y,int z,int xx):A(x,y,z)
{
d=xx;
}
}
实例
class Currency
{
poublic:
double par_value;
Currency(){per_value=0.0;}
Currency(double d){per_value=d;}
Currency(Currency &rc){par_value=rc.par_value;}
Currency & operator={Currency & c}
{
par_valuc=c.par_value;
return * this;
}
Currency & operator+(Currency & c)
{
par_value+=c.par_value;
return *this;
}
}
//人民币
class RMB:public Currency
{
public:
RMB():Currency(){};//调用派生类的构造函数前,需要调用器基类的工造函数
RMB(double d):Currency(d){};
RMB(Currency& c):Currency(c){};
RMB(RMB& rmb):Currency(rnb){};
friend ostream& operator<<{ostream& os,RMB& rnb};//派生类的附加功能
};
ostream& operator<<{ostream& os, RMB& rmb} //output 运算符不能是一个类的成员函数
{
os<<"¥"<<setiosflags(ios::shwopoint|ios:fixed)<<setprecision(2)rmb.par_value;
return os;
}
void main()
{
RMB r_income(5000);
RMB r_balance;
r_balance=r_income=r_expense;
cout<<"income"<<r_income<<endl;
}
4 将iostream 运算符重载
1)ostream & operator<< (ostream &os,const Triangular & ths)
{
os<<"("<<rhs.beg_pos()<<","<<rhs.length()<<")";
rhs.display(rhs.length(),rhs.beg_pos(),os);
}
ouutput 运算符不能够设计成member function
2)istream& operator>>(istream &is,Triangular &rhs)
{
char ch1,ch2;
int bp,len;
//输入 ch1='(',bp=3,ch3=',' len=6
is>>ch1>>bp>>ch2>>len;
rhs.beg_pos(bp);
rhs.length(len);
rhs.next_reset();
return is;
}
Triangular tris;
cin>>tri2
4 虚基类
载继承关系中,同一基类被继承多次,不仅会引器歧异,而起可能浪费空间
class A
{
public:
int value;
};
class B:public virtual A(); //虚基类 编译器只产生一个基类版本。如果不定义为virtual 编译器不知到调用那个value 了,当然
class C:public virtual A();// 也可以return B::value;
class D:public b.public c
{
public
int GetValue(){return value;}
};
void main()
{
D dd;
dd.GetValue();
}
5 多态形,和虚函数
class TFirst
{
public virtual void Display();
};
void TFirst::Display()
{
cout<<"first "
}
class TSecond:public TFirst
{
public:
virtual void Display();
};
void TSecond::Display()
{
cout<<"second"
}
void Display(TRist * pFirst)
{
pFisrt=>Display();
}
void main()
{
TFirst * pFirst=new TFirst;
TSecond * pSecond=new TSecond;
pFirst->Display();
pSecond->Display();
Display(pFirst);
Display(pSecond);
delet pfirst ;
delet pSecond;
getch();
}
c++ builder 中的集合的
1 集合的概念基本
Set<type,minval,maxval>
Set<char,'A','C'> s1
tydefef Set(char,1,255) UPPERCASet;
UPPERCASESet s1;
s1<<'A'<<'B'<<'C';
sysset.h 直接包含载vcl.h 中
2 集合的操作
#include<iostream>
#include<system.hpp>
#include<conio.h>
using namespace std;
typedef Set<char,'B','Z'> UpperSet;
typedef Set<char,'a','z'> LoverSet;
typeder Set<char,'a','j'> HalfLowerSet;
void set_example()
{
LowerSet ae,ae2,ac,de;
UpperSet AE,AE2,AC,DE;
HalfLowerSet aj;
}
异常处理
1 c++ 的异常处理
#include <iostream.h>
#include <conio.h>
class Crange
{
public:
int index;
CRange(int i){index=i;}
}
class CString
{
char a[100];
int len;
public:
CString(char * s)
{
Len=strlen(s);
strcpy(a,s);
}
char & operator[](int i)
{
if(i>0 && i<len) return a[i];
else throw CRange(i);
}
void DisplayNoCatch(CString & s)
{
int j;
for(j=0lj<20;j++)
cout<<s[j]<<""endl;;
}
int DisplayHasCatch(CString & s)
{
try{
DisplayNoCatch(s);
}catch(CRange r)
{
cerr<<r.index<<endl;
}
return 99;
}
}
2 多路捕捉
#include<iostream.h>
#include<conio.h>
void MultiException()
{
int i;
double d;
int no;
cout<<"(>0 and <5)";
cin>>no;
tyr
{
switch(no)
{
case 1;
throw 123;
break;
case 2:
throw i;
break;
case 3:
throw d;
break;
case 4:
throw "Error";
break;
default:
cout<<"error";
}
}
catch(int ie)
{
cout<<"int"<<endl;
}
catch(double de)
{
cout<<"double"<<endl;
}
catch(char* se)
{
cout<<"char"<<endl;
}
}
3 bcb中的异常类
1)却省vcl 异常处理 无try catch 自动处理
int i=4,j=0;k;
k=i/k;
//下一句永远不会执行
ShowMessage(k);
2) 引发vcl 异常类
try{
}
catch(Exception &e)
{
ShowMessage(e.,Message);
}
不能引发如int double 等简单类型的异常
3) c++ 异常处理
try
{
throw 2222;
}
catch(int ErrorCode)
{
ShowMessage(ErrorCode);
}
}
4 单一捕捉异常
try{
k=10/0;
}catch(EDivByZero & E)
{
MessageDlg()
}
5 捕捉所有异常
try
{
}catch(...) or(EExternalException &E)