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>

 

posted on 2021-11-28 13:56  Desktop  阅读(95)  评论(0)    收藏  举报