CPP——封装

认识类

其内变量为成员变量,函数叫成员函数,有private,public,protected三种类型

#include<iostream>
using namespace std;

class student{    //student指代类名
    private://隐私,除非通过公开内的访问,否则不可访问
    
    public://公开,可以在结构外直接调用
    student();//构造函数
    student(char *, char *);
    ~student();//析构函数
    void add();//若在类内定义函数,要在main函数内调用它,则要加上类名称去调用它,不加参数,可加数据类型
    void add(double);//同名函数在cpp是允许的,运用括号内加数据类型区分
};

student::student(char *n1. char *n2)//定义了与类名一样的函数,需手动补充构造函数与析构函数
{
    ………………;
}

void a::add(int a,int b)//定义类内的函数要加上类名称及两个冒号
{
    ………………;
}

int main()
{
    a.add(参数);//加上类名去调用它
    
    return 0;
}

与struct的区别

class定义的内容默认为隐私的,struct默认为公开的

在c语言中,struct只能有成员变量,不能有成员函数,而cpp可以有成员函数

构造函数

使用指针时,用new会调用一次构造函数(函数名与类名相同的函数叫构造函数)

student();//构造函数,此构造函数是不带参数的
student(char *, char *);//一般如果不定义一个与类名一致的带参数的构造函数,系统会自动补充(缺省函数)此函数,但是若定义了,则需要手动补充上一个函数

析构函数

使用指针时,用delete会调用一次析构函数(~加构造函数叫析构函数),不能带参数!!!

~student();//析构函数
//当使用delete时,系统会在类内自动补充,但是若定义一个与类名一致的带参数的构造函数,则需要手动补充(缺省函数)此函数

类/结构的复合

在类私密成员内还有类,则必须进行初始化,否则程序会错误

若两个类内都有new,则delete时各自在类内用析构去除

在student类内无法访问date的私密成员

#inlude<iostream>
using namespace std;

struct date{
    int y, m, d;
    void setdate();
};

class student{    //student指代类名
    private://隐私,除非通过公开内的访问,否则不可访问
    	date birthday;
    	int chinese;
    
    public://公开,可以在结构外直接调用
        student();//构造函数
        student(char *, char *);
        ~student();//析构函数
        void add();//若在类内定义函数,要在main函数内调用它,则要加上类名称去调用它,不加参数,可加数据类型
        void add(double);//同名函数在cpp是允许的,运用括号内加数据类型区分
};

student::student(int y, int m, int d, int chinese)birthday(y, m, d),chinese(80)//当遇到类内有另外一个类或结构,可以用此方式为其内变量初始化
{
    birthday.setdate(y, m, d);//也可以这样子初始化
}

int main()
{
    student(y, m, d, chinese);
}

this指针

只能用于第一层类里面,在嵌套中不可使用它去调用第二层的类

class student{   
    private:
    	int x, y;
    
    public:
        student();
        student(char *, char *);
        ~student();
        void add();
        void add(double);
};

void student::add(int x, int y)
{
    this->x = x;
    this->y = y;//this指针,当传入参数同名时可以用它进行区分
}

int main()
{
    add(x,y)
}

拷贝构造函数

当发生类类型的变量发生参数传递时,会调用一次

#include<iostream>
using namespace std;

struct date{
    int y, m, d;
    void setdate();
};

class student{   
    private:
    	date birthday;
    	char *name;
    
    public:
        student(const student&);//系统会自行补,但是是浅拷贝;当当类内有new时,便要自己写一个深拷贝函数
        student(char *, int, int, int);
        ~student(){delete []name;}
};

student::student(char *p, int y, int m, int d)birthday(y, m, d)
{
   name = new char[srelen(p) + 1];
    strncpy(name, p, strlrn(p));//括号内第一个为拷贝的目的地,第二个为要拷贝的东西,拷贝长度
}

student::student(const student &s)//此函数为深拷贝
    :birthday(s.birthday)//将birthday初始化为s的birthday,此时会自动补拷贝构造函数
    {
        name = new char [strlen(s.name) + 1];
        strncpy(name, s.name, strlen(s.name));
	}

void print(student s)
{
    ………………
}

int main()
{
    student(p, y, m, d);
    print(s);//此时发生了类类型参数传递,故会调用拷贝调用函数,但是因为类内有new,所以要自己写一个深拷贝
    return 0;
}

类的总结

  • 因为利用类传递参数会引起构造函数与析构函数的调用,增加时间与空间复杂度,故而推荐用引用与指针传递参数或其他

  • 无这种形式

//point是一个类,有x,y两个私密成员
point *p;
int x, y;
cin >> x >> y;

point *(p) (x, y);//这种形式是不行的,此函数为类内的构造函数
point p[1] (x, y);//这样子可以
//或者
p->setx(x)//setx(x)是类内的成员函数,这样子也可以,x,y分开设置即可
  • 一般情况下不用实现拷贝构造函数,当类内有new时就一定要加

  • 无论是定义还是函数返回值,使用一次类或结构时,都会调用一次构造函数和析构函数,指针与函数形参除外

静态static

  • 可以定义成员变量,也可定义函数

  • 静态函数没有this指针,而成员函数及构造函数都有this指针

  • 调用静态函数的写法

    #include<iostream>
    using namespace std;
    
    class Student
    {
        private:
        string age;
        int num;
        int age;
        static int count;//不属于任何一名同学,故定义成静态变量
        static int totalAge;//不属于任何一名同学,故定义成静态变量
        public:
        Student(string, int, int);
        void total();
        static float averageAge();//无this指针,只能访问static定义的变量,其他成员变量不能访问
    };
    
    student::student(string name1, int num1, int age1)
        :name(name1),num(num1)
        {
            age = age1;
        }
    
    void Student::total()
    {
        totalAge += age;
        count++;
    }
    
    float Student::averageAge()
    {
        return totalAge*0.1/count;
    }
    
    int Student::count = 0;
    int Student::totalAge = 0;//静态成员变量需要初始化,格式像这样
    
    int main()
    {
        Student::averageAge();//这样子调用
        ………………
    
            return 0; 
    }
    

友元friend

当程序员将成员变量设置为私密时,未授权人员无法访问,增强了安全性。但当一定要访问时,可用友元。

  • 可不是成员函数,不属于类
  • 可以修改成员信息
  • 可以设置其他类为friend**(注意!友元是单向的,在student内将date设置为friend。date可访问student的private,但是student不可以访问date的private【简单理解为我把你当朋友,你不把我当朋友】)**,也可设置其他类内单独函数
#include<iostream>
using namespace std;

calss date
{
private:
	………………;
    
public:
    function1;
    function2;    
};

class Student
{
private:
    string age;
    int num;
    int age;
    static int count;
    static int totalAge;
public:
    Student(string, int, int);
    void total();
    static float averageAge();
    friend void print(Student * / Student &);//将参数设置为指针或引用,指向类的内容首地址,便可访问
    friend function1;//设置其他类内函数为friend
    friend class date;//设置其他类为friend
};

void print(Student &p)
{
    cout << s.name
        << s.num
        <<s.age;
}

int main()
{
    ………………

        return 0;
}

小技巧

  • 当遇到新创建的类内用到后创建的类,则可在其前先定义类
#include<iostream>
using namespace std;

class Student;//像这

class date
{
private:
	………………;
    
public:
    function1;//假设函数涉及到student,但是student在后面,放在前面student内也涉及到date,这时候便在前面提前定义
    function2;    
};


class Student
{
private:
    string age;
    int num;
    int age;
    static int count;
    static int totalAge;
public:
    Student(string, int, int);
    void total();
    static float averageAge();
    friend void print(Student * / Student &);
    friend function1;
    friend date;
};

void print(Student &p)
{
    cout << s.name
        << s.num
        <<s.age;
}

int main()
{
    ………………

        return 0;
}

在C++中,可以用const来定义一个const对象,但const对象不可以调用类中的非const成员函数

引发原因:: 由调用成员函数时隐式传入的当前对象的this指针引起。

  • 非const成员函数中的隐式参数:classA* this
  • const成员函数中的隐式参数:const classA* this
    根本原因:
  • const对象的指针为const classA* this,因此传入非const成员函数时编译器报错(类型不匹配,无法从const 指针转换为非const指针);但传入const成员函数则类型匹配。
  • 非const对象的指针为classA* this,可以调用const成员函数,因为const修饰符保证了不会修改该对象。
//错误形式
void print(const int* p);
//正确形式
void print(const int* p)const;
  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值