C++ 语言学习 day10 复习(1)

1.
/********* 探讨权限 ************
 * 权限|位置    类外  类内  派生
 * 公有:       √     √    √
 * 保护:       ×     √    √
 * 私有:       ×     √    ×

 * 总结:
 *      类外:只能访问公有成员
 *      类内:可访问所有成员
 *      派生:无法访问祖先类的私有成员
 *
 * 注意:
 *      C++中权限关键字开始位置就是权限
 *      直到下一个权限关键字或者类结束
 * ****************************/

******************************************************
 * 什么时候使用相关权限?
 * 公有:一般想让外界直接访问的之后使用公有权限,类似接口函数
 * 保护:既不想要外部访问,但是又想让派生类继承使用则使用保护权限
 * 私有:只允许内部自己访问,派生无法访问
 * ******************************************************/
 


2.


/********* 构造函数 和 析构函数 ***************
 *构造函数:
 *  作用:用于申请空间时初始化处理
 *  定义:
 *      1.函数名与类名相同
 *      2.无返回值
 *      --->通过从上定义规则可以发现,构造函数可以拥有参数,则可实现重载
 *析构函数:
 *  作用:用于销毁时做释放处理
 *  定义:
 *      1.函数名与类名相同,但多了一个~号
 *      2.无参,无返回值
 *      --->然通过以上定义规则发现,析构函数无法重载
 * 注意:
 *  如果用户没有提供构造和析构以及拷贝等函数则编译器默认提供
 *  1.无参构造
 *  2.拷贝构造(浅)
 *  3.析构函数
 *  4.=运算符函数
 * ******************************************/

代码:

#include 
#include 
using namespace std;

/********* 构造函数 和 析构函数 ***************
 *构造函数:
 *  作用:用于申请空间时初始化处理
 *  定义:
 *      1.函数名与类名相同
 *      2.无返回值
 *      --->通过从上定义规则可以发现,构造函数可以拥有参数,则可实现重载
 *析构函数:
 *  作用:用于销毁时做释放处理
 *  定义:
 *      1.函数名与类名相同,但多了一个~号
 *      2.无参,无返回值
 *      --->然通过以上定义规则发现,析构函数无法重载
 * 注意:
 *  如果用户没有提供构造和析构以及拷贝等函数则编译器默认提供
 *  1.无参构造
 *  2.拷贝构造(浅)
 *  3.析构函数
 *  4.=运算符函数
 * ******************************************/

class People
{
public:
    People();   /*无参构造*/
    People(string name,int age,string sex = "女");   /*带参构造*/
    People(const People &people);                    /*拷贝构造*/

    ~People();  /*析构函数*/
public:
    void Print() const;/*接口函数*/
    void operator =(const People &people) /*=号赋值运算符*/
    {
        this->m_name = people.m_name;
        this->m_age = people.m_age;
        this->m_sex = people.m_sex;
        cout << "=号赋值运算符" << endl;
    }
protected:
    string m_name;  /*姓名*/
    int m_age;      /*年龄*/
    string m_sex;   /*性别*/
};
/***** 类外实现 *****/
People::People()    /*无参构造*/
{
    this->m_name = "";
    this->m_age = 0;
    this->m_sex = "女";
    cout << "无参构造" << endl;
}

People::People(string name,int age,string sex)/*带参构造*/
{
    this->m_name = name;
    this->m_age = age;
    this->m_sex = sex;
    cout << "带参构造" << endl;
}

People::People(const People &people) /*拷贝构造*/
{
    this->m_name = people.m_name;
    this->m_age = people.m_age;
    this->m_sex = people.m_sex;
    cout << "拷贝构造" << endl;
}

People::~People()  /*析构函数*/
{
    cout << "析构函数" << endl;
}

void People::Print() const
{
    cout << "\t姓名:" << this->m_name
         << "\t年龄:" << this->m_age
         << "\t性别:" << this->m_sex
         << endl;
}

int main()
{
    /*1.实例化对象*/
    People people1;                   /* 默认调用无参 */

    People people2("张三",18,"男");    /*带参构造*/
    People people3("李四",17);        /*带参构造*/

    People people4(people2);    /*拷贝构造*/

    People people5 = people2;   /*拷贝构造*/
    people5 = people3;          /*=号赋值运算符*/
    /********* 输出结果内容 **********/
    cout << "\npeople1:" << endl;
    people1.Print();

    cout << "\npeople2:" << endl;
    people2.Print();

    cout << "\npeople3:" << endl;
    people3.Print();

    cout << "\npeople4:" << endl;
    people4.Print();

    cout << "\npeople5:" << endl;
    people5.Print();
    return 0;
}


3.
/*********** 浅拷贝 Vs 深拷贝 *************************
 *浅拷贝: 是值拷贝,针对指针变量,则都是指向到同一片内存空间地址
 *      会造成:①一个操作多个对象 ②多次析构照成程序崩溃
 *深拷贝: 在堆区申请空间的操作都要实现
 *      注意:一般牵扯指针操作,都会自己实现深拷贝
 ****************************************************/

代码:

#include 
#include 
using namespace std;

/*********** 浅拷贝 Vs 深拷贝 *************************
 *浅拷贝: 是值拷贝,针对指针变量,则都是指向到同一片内存空间地址
 *      会造成:①一个操作多个对象 ②多次析构照成程序崩溃
 *深拷贝: 在堆区申请空间的操作都要实现
 *      注意:一般牵扯指针操作,都会自己实现深拷贝
 ****************************************************/
class A{
public:
    A(){cout << "A的构造函数" <a = new A;  /*申请空间,修改指向*/
        *this->a = *people.a;/*拷贝内容到新的空间*/
        cout << "深拷贝构造函数" << endl;
    }

    ~People()
    {
        delete a;   /*释放*/
    }
public:
    A *a;    /* 类成员指针 */
};


int main()
{
    /***** 打印大小 *****/
    cout << "sizeof(string) = " << sizeof(string) << endl;
    cout << "sizeof(A) = " << sizeof(A) << endl;
    cout << "sizeof(People) = " << sizeof(People) << endl;
    /***** 1.实例化对象 ****/
    People *people = new People;

    people->a->name[0] = "张三";


    People people1(*people); /* 拷贝构造 */
    people1.a->name[0] = "李四";

    cout << "people->a->name[0]" << people->a->name[0] << endl;
    cout << "people1.a->name[0]" << people1.a->name[0] << endl;

    delete people;
    return 0;
}

4.

/****** 程序的执行顺序(初始化顺序) **************
 * 1.自上而下
 * 2.从左往右
 * 总结:初始化列表不会影响正常初始化顺序
 * 总结:析构顺序与初始化顺序相反
 * *****************************************/

代码:

other.h

#ifndef OTHER_H
#define OTHER_H
#include 
using namespace std;

class A{
public:
    A(){cout << __func__<< endl;}
    A(int xx){cout << __func__<< endl;}
    ~A(){cout << __func__<< endl;}
};

class B{
public:
    B(){cout << __func__<< endl;}
    B(int xx){cout << __func__<< endl;}
    ~B(){cout << __func__<< endl;}
};

class C{
public:
    C(){cout << __func__<< endl;}
    ~C(){cout << __func__<< endl;}
};

class D{
public:
    D(){cout << __func__<< endl;}
    ~D(){cout << __func__<< endl;}
};

/**** 人类中包含A和B *****/
class People : public C,public D{
public:
    People()
    :b(20),a(10)/*初始化列表 父类构造 -> 成员*/
    {cout << __func__<< endl;}
    ~People(){cout << __func__<< endl;}
public:
    A a;
    B b;
};

class Student
{
public:
    Student(string name,int age)
        :m_name(name),m_age(age)
    {

    }
public:
    string m_name;
    int m_age;
};

#endif // OTHER_H

main.c

#include 
#include "Other.h"
using namespace std;
/****** 程序的执行顺序(初始化顺序) **************
 * 1.自上而下
 * 2.从左往右
 * 总结:初始化列表不会影响正常初始化顺序
 * 总结:析构顺序与初始化顺序相反
 * *****************************************/
int main()
{
    /*1.实例化People */
    People people; // C -> D -> A -> B -> People

    Student stu("张三",18);
    cout << stu.m_name << "\t" << stu.m_age << endl;

    return 0;
}/* 调用析构: ~People -> ~B -> ~A -> ~D -> ~C */

5.

/******** 常量成员 ***************************************
 * 通过前面的铺垫,我们初始化列表专门给常量成员做初始化操作
 * 分类:
 *      常量成员属性:
 *          定义:在变量名之前加 const
 *          作用:只初始化赋值一次,以后无法更改,必须由 "初始化列表" 操作
 *      常量成员函数:
 *          定义:在函数参数后加 const
 *          作用:该函数不可修改类成员属性值,只可访问
 *              自己在函数中定义的变量可以修改
 *          注意:一般读取函数都会写成const常函数
 *
 *      常对象只能访问常函数,后面set容器存放的都会变成常对象
 * *****************************************************/

代码:

#include 

using namespace std;
/******** 常量成员 ***************************************
 * 通过前面的铺垫,我们初始化列表专门给常量成员做初始化操作
 * 分类:
 *      常量成员属性:
 *          定义:在变量名之前加 const
 *          作用:只初始化赋值一次,以后无法更改,必须由 "初始化列表" 操作
 *      常量成员函数:
 *          定义:在函数参数后加 const
 *          作用:该函数不可修改类成员属性值,只可访问
 *              自己在函数中定义的变量可以修改
 *          注意:一般读取函数都会写成const常函数
 *
 *      常对象只能访问常函数,后面set容器存放的都会变成常对象
 * *****************************************************/
class People
{
public:
    People():value(10)
    {

    }
public:
    /**** 成员属性 ****/
    const int value;
    int m_temp;
public:
    /**** 成员函数 ****/
    void Print() const
    {
        /* 访问 */
        cout << "value = " << value << endl;
        cout << "m_temp = " << m_temp << endl;
        /* 修改 */
        //m_temp = 500;
        /* 自定义函数变量可修改 */
        int xxx = 10;
        xxx = 50;
    }

    void SetTemp(int temp)
    {
        m_temp = temp;
    }
    int temp() const;
};


int main()
{
    People people;
    people.Print(); /* 调用 const 成员函数 */
    people.SetTemp(50);/* 调用 非const 成员函数 */

    const People peo;
    peo.Print();/* 调用 const 成员函数 */
    //peo.SetTemp(50);/* 调用 非const 成员函数 */ 报错: 常对象只能调用常函数

    return 0;
}


int People::temp() const
{
    return m_temp;
}


6.

/********** this 指针和空指针 *********
 * 都是指向到自己的指针
 * *********************************/

代码:

#include 

using namespace std;
class People
{
public:
    People(string name = "wu",int age = 0) : m_name(name),m_age(age){}    /* 构造函数 */
    void Print();
    void SetValue(int value);
public:
    string m_name;
    int m_age;
    int value;  /*注意这个成员*/
};

/********** this 指针和空指针 *********
 * 都是指向到自己的指针
 * *********************************/

void People::Print()
{
    /**** this指针案例 ****/
    cout << "name = " << this->m_name << endl;
    printf("this = %p\n",this);

    /**** 空指针案例 : 会造成同名问题,所以使用this指针解决*****/
    cout << "name = " << m_name << endl;
    cout << "value = " << value << endl;
}

/** 发现类成员属性名与函数参数名重名 **/
/** 根据调用优先级规则,谁定义得近调用谁**/
void People::SetValue(int value)
{
    /** 在这里设置会不产生任何效果:因为 value是栈自己定义的会随着销毁 **/
    value = value;
    /** 可以 使用this指针解决该问题 **/
    this->value = value;
}

int main()
{
    People people;
    people.SetValue(500);
    people.Print();

    People *ptr = &people;
    printf("ptr = %p\n",ptr);

    return 0;
}

7.

/********  静态成员特征 *********
 * 公有特征:
 *      1.可以通过对象 或 类名访问
 *      2.所有对象公用同一静态变量空间
 *
 * 静态成员属性:
 *      注意:类内声明,类外初始化
 *      常用:用作数据记录
 *      须知:
 *          1.所有对象共享同一份数据
 *          2.空间在编译阶段就已经分配
 *          3.静态成员不占用对象空间
 * 静态成员函数:类内声明类外实现也可以,类内实现也可以
 *      注意:静态成员函数不能使用非静态成员,所以也不能访问this指针
 *      常用:接口处理(数据集,固定参数"串口参数,摄像头参数,音频参数,网络参数等")
 *
 * ***************************/

代码:

#include 
#include 
using namespace std;

class People
{
public:
    People(){
        s_value++;
    }
public: /* 成员函数 */
    static void GetValue()  /* 静态成员函数 */
    {
        cout << "我是静态成员函数" << endl;
        cout << "s_value = " << s_value << endl;
        //cout << "m_value = " << m_value << endl; 报错:静态成员函数不能使用非静态成员
    }

    static string GetIP()
    {
        return "IPV4 192.168.1.100";
    }

    static int GetMax(int value1,int value2)
    {
        return value1 > value2 ? value1 : value2;
    }

public: /* 成员属性 */
    static int s_value;    /*静态成员属性:类内声明,类外初始化*/
    int m_value;
};
/********  静态成员特征 *********
 * 公有特征:
 *      1.可以通过对象 或 类名访问
 *      2.所有对象公用同一静态变量空间
 *
 * 静态成员属性:
 *      注意:类内声明,类外初始化
 *      常用:用作数据记录
 *      须知:
 *          1.所有对象共享同一份数据
 *          2.空间在编译阶段就已经分配
 *          3.静态成员不占用对象空间
 * 静态成员函数:类内声明类外实现也可以,类内实现也可以
 *      注意:静态成员函数不能使用非静态成员,所以也不能访问this指针
 *      常用:接口处理(数据集,固定参数"串口参数,摄像头参数,音频参数,网络参数等")
 *
 * ***************************/

/** 静态成员属性类外初始化 **/
int People::s_value = 0;


int main()
{
    /* 1.实例化对象 */
    //People people;

    /* 2.调用对象 */
    /* 2.1 实例对象调用静态成员 */
    //cout << people.s_value << endl;

    /* 2.2 通过类名调用静态成员 */
    //cout << People::s_value << endl;
    //People::GetValue();

    /* 2.3 通常静态成员属性做记录数据 */
    //cout << "当前女娲造人:" << People::s_value << endl;
    //{People people;}
    //cout << "当前女娲造人:" << People::s_value << endl;
    //{People people;}
    //cout << "当前女娲造人:" << People::s_value << endl;
    //{People people;}
    //cout << "当前女娲造人:" << People::s_value << endl;
    //{People people;}
    //cout << "当前女娲造人:" << People::s_value << endl;

    /* 2.4 通常静态函数做接口使用 */
    cout << People::GetIP() << endl;

    cout << People::GetMax(10,20) << endl;

    /* 2.5 静态成员不占用类空间 */
    cout << "sizeof(People) = " << sizeof(People) << endl;

    /* 3.销毁对象 */

    return 0;
}

你可能感兴趣的:(C++,语言的学习,学习)