• <C++> 类(4):静态成员变量和函数 浅拷贝和深拷贝(拷贝构造 operator=)


    一.静态成员变量和函数

    1.静态成员变量:

    ①如果在类中放了静态static成员变量 一定要在源文件即.cpp中 类外 给这个变量进行初始化

    初始化时要有:类型 类名 作用域

    1 int CPerson::a = 100;

    注意:一定要在定义CPerson类的后面初始化 不然会说不认识CPerson

    ②static变量在编译期的时候就存在了

    不用定义对象调用 通过类名和作用域就可以调用:“类名::静态变量名” 这样就可以直接使用

    ③当一个类中只放了一个静态成员变量的时候 这个类的大小:sizeof(类名) = 1

    但是一个类中只放了一个int类型的成员变量 那么这个类的大小:sizeof(类名) = 4

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class Cperson
     5 {
     6 public:
     7     int a;
     8 };
     9 
    10 class CPerson
    11 {
    12 public:
    13     static int a;
    14 };
    15 
    16 int CPerson::a = 100;
    17 
    18 int main()
    19 {
    20     cout << sizeof(Cperson) << endl;
    21     cout << sizeof(CPerson) <<endl;
    22 }

    输出结果:4 1

    ④定义对象不会再给static变量申请新的空间

    static是属于类的 一个类的所有对象共享一个static变量

    也就是说 无论一个类定义了多少了对象 对static进行操作 都是对同一个变量进行操作

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class CPerson
     5 {
     6 public:
     7     static int a;
     8 };
     9 
    10 int CPerson::a = 100;
    11 
    12 int main()
    13 {
    14     CPerson ps1;
    15     CPerson ps2;
    16     ps1.a = 1000;
    17 
    18     cout << ps1.a << endl;
    19     cout << ps2.a << endl;
    20 }

    输出结果:两个输出都是1000 足以说明一个类声明的所有对象 共用一个static变量

    2.静态成员函数:

    静态函数只能用static成员 不能用非静态成员(因为静态函数没有this指针)

    ②同样 静态函数也是没有对象就可以调用这个函数:“类名::静态函数名”直接调用

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class CPerson
     5 {
     6 public:
     7     static int a;
     8     int b;
     9 public:
    10     static void Show()
    11     {
    12         cout << a << endl;
    13         //cout << b << endl; 
    14         //如果放开上面一行就会报错 因为静态成员函数只能用static成员
    15     }
    16 };
    17 
    18 int CPerson::a = 100;
    19 
    20 int main()
    21 {
    22     cout << CPerson::a << endl;
    23     CPerson::Show();
    24 }

    二.拷贝构造

    1.引入:

    1 CPerson aa;
    2 CPerson bb(aa);

    第2行这样的语法在C++中是允许的 这就说明在类中 是有一个默认的构造函数的

    2.浅拷贝:(拷贝构造函数)

    1 CPerson(const CPerson& ps)
    2 {
    3     this -> a = ps.a;
    4 }

    3.深拷贝:

    1 CPerson(const CPerson& ps)
    2 {
    3     this -> a = new int;
    4     this -> a = ps.a;
    5 }

     4.浅拷贝和深拷贝的理解图:

    ①浅拷贝会出现的问题就是:在释放空间的时候 会出现一个空间删除两次的现象 会崩

    所以为了避免 尽量不使用值传递 或者用深拷贝也可以解决

    ②完成深拷贝必须知道new出来的空间是多大的

    对于我们来说 这块空间的大小和我们定义的成员有关 我们知道 但是系统不知道 所以内存默认的拷贝构造函数是浅拷贝

    5.总结:

    ①拷贝构造:第一个参数是当前这个类的const类型的引用的构造函数 叫做拷贝构造函数

    ②作用:复制一个对象

    ③注意:类中默认的是浅拷贝 会使两个对象使用一个空间 会出现同一个空间被释放两次的问题

    ④解决:函数参数用指针 引用 或者使用深拷贝

    所以在使用参数的时候 尽量不要直接给值 容器也一样 使用list<CPerson*> 而不是list<CPerson>

    三.operator=

    1.引入:

    1 CPerson aa;
    2 CPerson bb;
    3 aa = bb;

    第3行可以正常运行 就说明 系统中有一个默认的operator= 也是一个浅拷贝

    2.浅拷贝:

    1 CPerson& operator=(const CPerson& ps)
    2 {
    3     return *this;
    4 }

    默认的operator= 也是一个浅拷贝

    3.深拷贝:

    1 CPerson& operator=(const CPerson& ps)  
    2 {
    3     delete this->a;   // 创建对象的时候已经分配空间了 所以要删除原来的空间 
    4 
    5     this->a = new int;  //  重新分配
    6     *(this->a) = *(ps.a);
    7     return *this;
    8 }

    4.总结:

    ①在空类中 有4个默认函数:构造 析构 拷贝构造 和operator=

    ②拷贝构造和operator=都是浅拷贝

    ③拷贝构造的执行时间 是在对象创建的时候 而operator=的执行时间是两个对象用“=”赋值的时候

  • 相关阅读:
    Mkdocs文档生成
    IntelliJ IDEA
    WPS中页眉设置
    ubuntu下的画图工具-dia
    接口测试详细过程
    ubuntu下安装jmeter
    互联网产品接入支付功能如何测试?
    Uiautomator自动化测试编写和调试
    Ubuntu下配置android环境
    UIAutomator环境配置与运行
  • 原文地址:https://www.cnblogs.com/Aaaaaalei0612/p/9224752.html
Copyright © 2020-2023  润新知