C++类的制作
C++ 类定义
一个例子:
class test1{ private: int data1; protected: int data2; public: int data3; test1():data1(1),data2(2),data3(3){ } explicit test1(int a,int b=2,int c=3){ data1=a; data2=b; data3=c; } void setdata(int a){ data3=a; } ~test1(){ } };
关键字
class是定义类的关键字,typename与它同义.
test1是类名,你可以用 test1 a 来创建一个类a
private,protected,public都是类的关键字,在函数,变量前没有这三个关键字时,自动使用private
private 意为私有的,在类外的任何操作都不能调用其包含的变量,函数,除了它的友元类和友元函数
protected 意为受保护的,在类外的任何操作都不能调用其包含的变量,函数,除了它的友元类和友元函数,但以它为基类继承的类可以调用
public 意为公开的,在类外的任何操作都能调用其包含的变量,函数
在上面这个例子中,private包含了int data1;一个语句,protected包含了int data2;一个语句,public包含了int data3;一个语句和两个构造函数
构造
在上面这个例子中,类名为test1,所以类内的test1函数为构造函数
构造函数在类实例化时就被调用(实例化指执行了形如test1 a;test1 *b=new test1;的语句)
构造函数与普通函数相同,但当参数可以为一个时,才可以加上explicit关键字,意为显式的
在上面这个例子中,有两个构造函数
test1 a;语句会调用第一个无参的构造函数
test1 b(1,2,3),c(1,2),d(1);语句都会调用第二个构造函数,由于第二个函数的参数有默认值,所以有默认值的参数可以缺省,它将自动补为c(1,2,3),d(1,2,3)
test1 e=1;语句是非法的,应为有explicit关键字,删除explicit关键字后,test1 e=1;等同于test1 e(1);它将自动补为e(1,2,3)
析构
在上面这个例子中,类名为test1,所以类内的~test1函数为析构函数
析构函数在类失效时就被调用
析构函数与普通函数相同,通常为释放被占用的空间等
在上面这个例子中,有一个构造函数
ps:
如果没有构造,析构和拷贝函数编辑器将自动添加,如
class A { A() { } A& operator =(const A& a)//重载赋值函数 { memcpy(this, &a, sizeof(A)); return *this; } A(const A& a) { *this = a; //调用了赋值重载函数,this为指向自己的指针 } ~A() { } };
第二个例子:
class test2:public test1{ public: friend class test3; using test1::data2; test2(){ data3=0; } private: int data4; }; class test3{ public: void set(test2 &rhs){ rhs.data4=0; } };
继承
在定义类时,类名后加上冒号,继承方式和类名,代表继承
如 class 派生类类名 :继承方式(public,private,protected) 基类类名
如果有多个基类,每组继承方式,基类间用逗号分隔
派生类即继承类的类,基类即被继承的类
在上面这个例子中,test2继承了test1,所以它可以使用test1里的data2
关键字
using 意为使用,在上面这个例子中,test2使用test1里的变量和函数时,前面必须加上test1::
如 test1::setdata(1)
使用using后,前面不用加上test1::
如 data2
友元
友元分为友元类和友元函数,在上面这个例子中,test3时test2的友元函数,因此可以调用test2中私有的data4
第三个例子
class test4 { public: &operator=(test4&); &operator+(test4&); &operator+=(test4&); }; &test4::operator=(test4 &rhs) {} &test4::operator+(test4 &rhs) {} &test4::operator+=(test4 &rhs) {} bool operator==(test4 &lhs,test4 &rhs) {}
重载
重载可以让程序变得简洁,由于重载函数也是函数,因此可以用test4.operator=()的形式调用
在上面这个例子中,test4重载了=,+,+=三个运算符,
实际上,前置++,--,后置++,--,+=,-=,=,[],->,>>,<<,*,&,!,|,^等运算符必须在类内提前声明,
==,!=,>,<,>=,<=等运算符可以在类外直接定义
第四个例子
template<class T> class test5 { public: T data; };
模板
如果你熟悉STL库,你肯定知道vector<int>,queue<float>等定义
其实,它们是模板类
模板类和类一样,但在模板类声明前有模板声明
在上面这个例子中,template<class T>就是模板声明
模板类声明总是形如
template<模板1,模板2...>
class xxx{}
在实例化模板类时,必须在类名后的尖括号内加上模板,每个模板间用逗号隔开
在上面这个例子中,test5的声明为test5<int> a;test5<char> b;等
同样,模板也可以有默认值,在模板缺省时,他将自动按默认值补全,如
template<class T,class TT=int> class test6 { public: T data; TT data2; };
如果用test6<int>声明,他将自动补全为test6<int,int>
浙公网安备 33010602011771号