随笔 - 110,  文章 - 0,  评论 - 0,  阅读 - 18408

 对象的初始化和清理

  • 生活中我们买的电子产品都基本会有出厂设置,在某一天我们不用时候也会删除一些自己信息数据保证安全
  • C++中的面向对象来源于生活,每个对象也都会有初始设置以及 对象销毁前的清理数据的设置。

4.2.1 构造函数和析构函数

对象的初始化和清理也是两个非常重要的安全问题

​ 一个对象或者变量没有初始状态,对其使用后果是未知

​ 同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题

c++利用了构造函数和析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。

对象的初始化和清理工作是编译器强制要我们做的事情,因此如果我们不提供构造和析构,编译器会提供

编译器提供的构造函数和析构函数是空实现。

  • 构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
  • 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。

构造函数语法:类名(){}

  1. 构造函数,没有返回值也不写void
  2. 函数名称与类名相同
  3. 构造函数可以有参数,因此可以发生重载
  4. 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次

析构函数语法: ~类名(){}

  1. 析构函数,没有返回值也不写void
  2. 函数名称与类名相同,在名称前加上符号 ~
  3. 析构函数不可以有参数,因此不可以发生重载
  4. 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     person()
 7     {
 8         cout << "person的构造函数" << endl;
 9     }
10     ~person()
11     {
12         cout << "person的析构函数函数" << endl;
13     }
14 };
15 //构造与析构都必须有实现,如果我们不提供,编译器会自动提供一个空实现的构造与析构·
16 void test01()
17 {
18     person p;//栈区函数,函数结束后会自动重置
19 }
20 
21 int main()
22 {
23     //test01();
24     person p;
25     system("pause");//再按任意键之前main函数不会结束所以析构函数不会出现
26     return 0;
27 }
复制代码

 

 

 

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     person()
 7     {
 8         cout << "person的构造函数" << endl;
 9     }
10     ~person()
11     {
12         cout << "person的析构函数函数" << endl;
13     }
14 };
15 //构造与析构都必须有实现,如果我们不提供,编译器会自动提供一个空实现的构造与析构·
16 void test01()
17 {
18     person p;//栈区函数,函数结束后会自动重置
19 }
20 
21 int main()
22 {
23     test01();//执行完后析构函数将自动出现
24     //person p;
25     system("pause");
26     return 0;
27 }
复制代码

 

 

 

构造函数分类与三种输出方法:
分类与括号法:
复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     //构造函数按参数分为: 有参构造和无参构造(默认构造)
 7    //普通构造函数
 8     person()
 9     {
10         cout << "person 无参构造函数" << endl;
11     }
12     person(int a)
13     {
14         age = a;
15         cout << "person 有参构造函数" << endl;
16     }
17     //构造函数按类型分为: 普通构造和拷贝构造
18     //拷贝构造
19     person(const person& p)//const保证不修改原函数,用引用的方式是因为我们不是调用原函数
20     {
21         //将传入的人的所有的属性拷贝到当前对象上
22         age = p.age;
23         cout << "person 拷贝构造函数" << endl;
24     };
25     int age;
26 };
27 void test01()
28 {
29     //1.括号法
30     person p1;//无参构造函数
31    /* 注意事项1
32         调用默认构造函数时不要加()
33         因为编译器会认为是一个函数声明
34     person p1();
35     void fuc() 这就是函数声明;*/
36     person p2(10);//有参构造函数
37     person p3(p2);//拷贝构造函数 里面是p1 p2均可
38     cout << "p2年龄为" << p2.age << endl;
39     cout << "p3年龄为" << p3.age << endl;
40 }
41 int main()
42 {
43     test01();
44 }
复制代码

 

 

 显示法:

1  
2    // 显示法
3     person p1;
4     person p2 = person(10);//与括号法调用方式 :person p2(10);对比
5     person p3 = person(p2);//与括号法调用方式 :person p3(p2);对比

匿名对象:

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     //构造函数按参数分为: 有参构造和无参构造(默认构造)
 7    //普通构造函数
 8     person()
 9     {
10         cout << "person 无参构造函数" << endl;
11     }
12     person(int a)
13     {
14         age = a;
15         cout << "person 有参构造函数" << endl;
16     }
17     //构造函数按类型分为: 普通构造和拷贝构造
18     //拷贝构造
19     person(const person& p)//const保证不修改原函数,用引用的方式是因为我们不是调用原函数
20     {
21         //将传入的人的所有的属性拷贝到当前对象上
22         age = p.age;
23         cout << "person 拷贝构造函数" << endl;
24     };
25     ~person()
26     {
27         cout << "person 析构函数调用" << endl;
28     }
29     int age;
30 };
31 void test01()
32 {
33  person(10);//匿名对象 特点:当前执行结束后,系统会立即回收掉匿名对象
34     cout << "aaa";
35 }
36 int main()
37 {
38     test01();
39 }
复制代码

 

 

 

 

 注意事项二 :不要用拷贝构造函数初始化匿名对象

 

 

 隐式转换法

 1 person p4 = 25;//相当于写了 person p4 = person(10);有参构造函数

2 person p5 = p4;//拷贝构造函数 

 

 

拷贝构造函数调用时机

C++中拷贝构造函数调用时机通常有三种情况

  • 使用一个已经创建完毕的对象来初始化一个新对象
  • 值传递的方式给函数参数传值
  • 以值方式返回局部对象
复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     person()
 7     {
 8         cout << "person 的无参构造函数的调用" << endl;
 9     }
10     person(int age)
11     {
12         m_age = age;
13         cout << "person 的有参构造函数的调用" << endl;
14         cout << "参构造函数中的m_age:" << m_age << endl;
15     }
16     ~person()
17     {
18         cout << "person 的析构函数的调用" << endl;
19     }
20     person(const person& p)//传入类的别名并且限制修改类中的元素和修饰类的地址
21     {
22         cout << "person 的拷贝构造函数的调用" << endl;
23         //m_age = p.m_age;//24         //cout << "拷贝构造函数中的" << m_age << endl;
25         cout << "拷贝构造函数中的 p.m_age:" << p.m_age << endl;
26     }
27     int m_age;
28 };
29 //使用一个已经创建完毕的对象来初始化一个新对象
30 void test01()
31 {
32     person p1(20);
33     person p2(p1);
34 }
35 //2. 值传递(给一个函数的参数进行传值)的方式给函数参数传值
36 //相当于Person p1 = p;
37 void dowork(person p1)
38 {
39 
40 }
41 void test02()
42 {
43     person p;
44     dowork(p);//值传递的本质是给原函数拷贝一个副本出来输出,这符合拷贝构造函数的调用条件
45 }
46 //3. 以值方式返回局部对象
47 person dowork2()
48 {
49     person p1;//再执行完之后会释放掉,所以会触发析构函数调用
50     cout << (int*)&p1 << endl;//(int *) 是强制转化为整型指针类型,所以最后就是一个指向p1 的int 指针
51     return p1;//不会返回person p1中的p1,而是拷贝一份返回出去,这符合拷贝构造函数调用条件
52 }
53 void test03()
54 {
55     person p = dowork2();
56     cout << (int*)&p << endl;
57 }
58 int main()
59 {
60     //test01();
61     //test02();
62     test03();
63 }
64 
65  
复制代码

 

 

构造函数调用规则

默认情况下,c++编译器至少给一个类添加3个函数

1.默认构造函数(无参,函数体为空)

2.默认析构函数(无参,函数体为空)

3.默认拷贝构造函数,对属性进行值拷贝

构造函数调用规则如下:

  • 如果用户定义有参构造函数,c++不在提供默认无参构造,但是会提供默认拷贝构造

  • 如果用户定义拷贝构造函数,c++不会再提供其他构造函数

 

 

 

复制代码
 1 class Person {
 2 public:
 3     //无参(默认)构造函数
 4     Person() {
 5         cout << "无参构造函数!" << endl;
 6     }
 7     //有参构造函数
 8     Person(int a) {
 9         age = a;
10         cout << "有参构造函数!" << endl;
11     }
12     //拷贝构造函数
13     Person(const Person& p) {
14         age = p.age;
15         cout << "拷贝构造函数!" << endl;
16     }
17     //析构函数
18     ~Person() {
19         cout << "析构函数!" << endl;
20     }
21 public:
22     int age;
23 };
24 
25 void test01()
26 {
27     Person p1(18);
28     //如果不写拷贝构造,编译器会自动添加拷贝构造,并且做浅拷贝操作
29     Person p2(p1);
30 
31     cout << "p2的年龄为: " << p2.age << endl;
32 }
33 
34 void test02()
35 {
36     //如果用户提供有参构造,编译器不会提供默认构造,会提供拷贝构造
37     Person p1; //此时如果用户自己没有提供默认构造,会出错
38     Person p2(10); //用户提供的有参
39     Person p3(p2); //此时如果用户没有提供拷贝构造,编译器会提供
40 
41     //如果用户提供拷贝构造,编译器不会提供其他构造函数
42     Person p4; //此时如果用户自己没有提供默认构造,会出错
43     Person p5(10); //此时如果用户自己没有提供有参,会出错
44     Person p6(p5); //用户自己提供拷贝构造
45 }
46 
47 int main() {
48 
49     test01();
50 
51     system("pause");
52 
53     return 0;
54 }
复制代码

深拷贝与浅拷贝

深浅拷贝是面试经典问题,也是常见的一个坑

浅拷贝:简单的赋值拷贝操作

深拷贝:在堆区重新申请空间,进行拷贝操作

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     person()
 7     {
 8         cout << "person的默认构造函数调用" << endl;
 9     }
10     person(int age ,int height)
11     {
12         m_age = age;
13         m_height = new int(height);
14         cout << "person的有参构造函数调用" << endl;
15     }
16     int m_age;
17     int* m_height;
18     ~person()//析构代码的用途 : 释放构造函数在堆区的内存
19     {
20         if (m_height != NULL)
21         {
22             delete m_height;
23             m_height = NULL;
24         }
25         cout << "person的析构函数调用" << endl;
26     }
27     person(const person& p)
28     {
29         cout << "person拷贝构造函数调用的调用" << endl;
30         //系统会自动执行实现 m_ age = p.m_age;  m_height =p.m_height;
31         //但因为拷贝函数和原函数的height指向同一个地址开辟在堆区,释放时会有冲突,所以我们需要
32         //深拷贝操作
33         m_height = new int(*p.m_height);
34     }
35 };
36 void test01()
37 {
38     person p1(18,160);
39     cout << "p1 age is :" << p1.m_age  << ",and his height is : " << *p1.m_height<< endl;
40     person p2(p1);
41     cout << "p2 age is :" << p2.m_age << ",and his height is : " <<* p2.m_height << endl;
42 }
43 int main()
44 {
45     test01();
46 }
复制代码

 

 

 

 

 

 

 初始化列表

作用:

C++提供了初始化列表语法,用来初始化属性

语法:构造函数():属性1(值1),属性2(值2)... {}

初始化数据成员与对数据成员赋值的含义是什么?有什么区别?

 

 

首先把数据成员按类型分类并分情况说明:

  • 1.内置数据类型,复合类型(指针,引用)- 在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的
  • 2.用户定义类型(类类型)- 结果上相同,但是性能上存在很大的差别。因为类类型的数据成员对象在进入函数体前已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,调用构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)

注意点:

初始化列表的成员初始化顺序:

C++ 初始化类成员时,是按照声明的顺序初始化的,而不是按照出现在初始化列表中的顺序。

复制代码
1 class CMyClass {
2     CMyClass(int x, int y);
3     int m_x;
4     int m_y;
5 };
6 
7 CMyClass::CMyClass(int x, int y) : m_y(y), m_x(m_y)
8 {
9 };
复制代码

你可能以为上面的代码将会首先做 m_y=I,然后做 m_x=m_y,最后它们有相同的值。但是编译器先初始化 m_x,然后是 m_y,,因为它们是按这样的顺序声明的。结果是 m_x 将有一个不可预测的值。有两种方法避免它,一个是总是按照你希望它们被初始化的顺序声明成员,第二个是,如果你决定使用初始化列表,总是按照它们声明的顺序罗列这些成员。这将有助于消除混淆。

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     person(int a,int b ,int c) :m_a(a), m_b(b), m_c(c)
 7     {
 8 
 9     }
10     int m_a;
11     int m_b;
12     int m_c;
13 };
14 void test01()
15 {
16     person p(30,20,10);
17     cout << "m_a = " << p.m_a << endl
18         << "m_b = " << p.m_b << endl
19         << "m_c = " << p.m_c << endl;
20 
21 }
22 int main()
23 {
24     test01();
25 }
复制代码

 

 

 类对象作为类成员

C++类中的成员可以是另一个类的对象,我们称该成员为 对象成员

例如:

 1 class A {}

2 class B

3 {  A a;  } 

B类中有对象A作为成员,A为对象成员

那么当创建B对象时,A与B的构造和析构的顺序是谁先谁后?

复制代码
 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 class phone
 5 {
 6 public:
 7     string m_pname;//创建一个名为m_pname 的string型变量
 8     phone(string pname)
 9     {
10         m_pname = pname;
11         cout << "phone的构造函数调用" << endl;
12     }
13     ~phone()
14     {
15         cout << "phone的析构函数调用" << endl;
16     }
17 };
18 class person
19 {
20 public:
21     person(string name,string pname):m_name(name), m_phname(pname)
22     {
23         cout << "person的构造函数调用" << endl;
24     }
25     ~person()
26     {
27         cout << "person的析构函数调用" << endl;
28     }
29     phone m_phname;//m_phname 为phone类的变量
30     string m_name;
31 };
32 void test01()
33 {
34     //当类中成员是其他类对象时,我们称该成员为 对象成员
35     //构造的顺序是 :先调用对象成员的构造,再调用本类构造
36     //析构顺序与构造相反,因为栈区有先进后出的原则
37     person p("张三","iphone");
38     cout << "名字 :" << p.m_name << ",手机 :" << p.m_phname.m_pname << endl;
39 }
40 int main()
41 {
42     test01();
43 }
复制代码

 

 

 静态成员

静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

静态成员分为:

  • 静态成员变量
    • 所有对象共享同一份数据
    • 在编译阶段分配内存
    • 类内声明,类外初始化
    • 复制代码
       1 #include <iostream>
       2 using namespace std;
       3 class person
       4 {
       5 public:
       6     //所有对象都共享同一份数据
       7     // 编译阶段就分配了内存
       8     //类内声明,类外初始化操作
       9     static int m_a;//类内声明,编译阶段分配了内存
      10     //静态成员变量也是有访问权限的
      11 private:
      12     static int m_b;
      13 };
      14 int person::m_a = 100;//类外初始化
      15 int person::m_b = 200;
      16 void test01()
      17 {
      18     person p;
      19     cout <<"修改前p.m_a :" <<  p.m_a << endl;
      20     person p2;
      21     p2.m_a = 200;
      22     cout << "利用p2修改后p.m_a :" << p.m_a << endl;//所有对象都共享同一份数据 ,当一个对象对数据进行修改,其他的对象共享的数据也变成了修改后的数据
      23     cout << "p2.m_a :" << p2.m_a << endl;
      24 }
      25 void test02()
      26 {
      27     //静态成员变量 不属于某一个对象上 所有对象都共享同一份数据
      28     //因此静态成员变量有两种的访问方式
      29     
      30     //第一种:通过对象进行访问
      31    /* person p;
      32     cout << p.m_a << endl;*/
      33     //第二种:通过类目进行访问
      34     cout << person::m_a << endl;
      35    // cout << person::m_b << endl; 类外访问不到私有的静态成员变量
      36 }
      37 int main()
      38 {
      39     //test01();
      40     test02();
      41 }


      复制代码

       

       

      • 静态成员函数
        • 所有对象共享同一个函数
        • 静态成员函数只能访问静态成员变量

       

      复制代码
       1 #include <iostream>
       2 using namespace std;
       3 //静态成员函数
       4 //所有对象共享同一个函数
       5 //静态成员函数只能访问静态成员变量
       6 class person
       7 {
       8 public:
       9     //静态成员函数
      10     static void func()
      11     {
      12         m_a = 100;//静态成员函数可以访问静态成员变量,所有对象共享的
      13         m_b = 200;//静态成员函数不可以访问非静态成员变量,无法区分到底是哪个对象的m_b属性;运行时会报错
      14         cout << "static void func()的调用" << endl;
      15     }
      16     static int m_a;//静态成员变量
      17 private:
      18     static void func2()
      19     {
      20         cout << "static void func2()的调用" << endl;
      21     }
      22 };
      23 int person::m_a = 0;//静态成员变量
      24 int m_b = 1;//非静态成员变量
      25 //有两种访问方式
      26 void test01()
      27 {
      28     //通过对象进行访问
      29     person p;
      30     p.func();
      31     //通过类名进行访问
      32     person::func();
      33     //person::func2();//错误操作,私有作用域下类外不可访问
      34 }
      35 int main()
      36 {
      37     test01();
      38 }
      复制代码

       

       C++对象模型和this指针

      4.3.1 成员变量和成员函数分开存储

      在C++中,类内的成员变量和成员函数分开存储

      只有非静态成员变量才属于类的对象上

    • 复制代码
       1 #include <iostream>
       2 using namespace std;
       3 //成员变量和成员函数是分开存储的
       4 class person
       5 {
       6     int m_a;//非静态成员变量 属于类的对象的
       7     static int m_b;//不属于类的对象上
       8     void func()//非静态成员函数 不属于类的对象上
       9     {
      10 
      11     }
      12     static void func2()//静态成员函数 不属于类的对象上
      13     {
      14 
      15     }
      16 };
      17 int person::m_b = 100;
      18 void test01()
      19 {
      20     person p;
      21     //空对象占内存:1
      22     //c++编译器会给每个空对象分配一个字节的内存空间,是为了区分空对象占内存的位置
      23     //每个空对象也应该有个独一无二的内存地址
      24     cout << "size of p =" << sizeof(p) << endl
      25         << "size of &p =" <<&p ;
      26 }
      27 void test02()
      28 {
      29     person p;
      30     cout << "size of p =" << sizeof(p) << endl
      31         << "size of &p =" << &p;
      32 }
      33 int main()
      34 {
      35     //test01();
      36     test02();
      37 }
      复制代码

 this指针概念

通过4.3.1我们知道在C++中成员变量和成员函数是分开存储的

每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码

那么问题是:这一块代码是如何区分那个对象调用自己的呢?

c++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用的成员函数所属的对象

 

 指向正在调用的成员函数

this指针是隐含每一个非静态成员函数内的一种指针

this指针不需要定义,直接使用即可

this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可使用return *this
复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     person(int age)
 7     {
 8         this -> age = age;//系统认为三个age是同一份和下面定义的 int age (属性age)不是一个东西,只有加上this->才能区分
 9     }
10     //this指针指向被调用的成员函数所属的对象,也就是指向现在调用的p1
11     int age;
12     person& personaddage(person& p)//如果 person& personaddage中不加&,那么调用函数时就会调用拷贝构造函数,return的是一个副本,然后当副本的p2和.personaddage(p1)发生关系,返回的又是一个新的副本p2,也就是相当于最后只有一个没用调用过然后.personaddage(p1)和一个.personaddage(p1)发生关系,最后结果就和p2、.personaddage(p1)一样,而不是p2.personaddage(p1).personaddage(p1).personaddage(p1);的结果40了
13     //用&的方式返回那么返回的是地址,不会调用拷贝构造函数,调用的一直都是最初的p2
14     {
15         this->age += p.age;//例如:“b+=c”,就是b = b+c的意思。
16         //调用test02时,this是指向p2的指针,而*this指向的就是p2这个对象的本体
17         return *this;
18     }
19 };
20 //解决名称冲突
21 void test01()
22 {
23     person p1(18);
24     cout << "p1的年龄为:" << p1.age << endl;
25 }
26 //返回对象本身用*this
27 void test02()
28 {
29     person p1(10);
30     person p2(10);
31     //链式编程思想
32     p2.personaddage(p1).personaddage(p1).personaddage(p1);//p2.personaddage(p1)执行完后因为返回值是p2,所以继续和后面的).personaddage(p1)发生关系
33     cout << "p2的年龄为:" << p2.age << endl;
34 }
35 int main()
36 {
37     //test01();
38     test02();
39 }
复制代码

 

 

空指针访问成员函数

C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

如果用到this指针,需要加以判断保证代码的健壮性

复制代码
 1 #include <iostream>
 2 using namespace std;
 3 class person
 4 {
 5 public:
 6     void showcalssname()
 7     {
 8         cout << "this is person class" << endl;
 9     }
10     void showpersonage()
11     {
12         //报错原因是因为传入指针为NULL也就是0;
13         //为了防止传入空指针我们可以这样做
14         if (this == 0)
15         {
16             return;
17         }
18         cout << "age :" << this->m_age << endl;//调用属性三前面都默认加了this->指针,系统自动加,这里加上只是为了演示
19     }
20     int m_age;
21 };
22 void test01()
23 {
24     person* p = 0;//因为这里指向空的地方,没有任何对象,所以this->没有指向一个确切的值,所以对象没用确定,哪里有年龄,所以调用p->showpersonage();会报错
25     //p -> showcalssname();
26     p->showpersonage();
27 }
28 int main()
29 {
30     test01();
31 }
复制代码

 const修饰成员函数

常函数:

  • 成员函数后加const后我们称为这个函数为常函数
  • 常函数内不可以修改成员属性
  • 成员属性声明时加关键字mutable后,在常函数中依然可以修改

常对象:

  • 声明对象前加const称该对象为常对象
  • 常对象只能调用常函数
复制代码
 1 #include <iostream>
 2 using namespace std;
 3 //常函数
 4 class person
 5 {
 6 public:
 7     //this指针的本质 是指针常量 指针的指向是不可以修改的,值是可以修改的
 8     // this 指针相当于person* const this; ,再加一个const 就相当于const person* const this;
 9     //在成员函数后面加const,修饰的是this指针,相当于常量this指针,让指针指向的值也不可以修改
10     void showperson() const
11     {
12         //this->m_a = 100;//类内的变量系统都默认加了this->修饰,加了const后不允许修改
13         //this = NULL;//this指针是不可以修改指针指向的
14         this->m_b = 100;
15     }
16     void func()
17     {
18         m_a = 100;
19     }
20     int m_a;
21    mutable int m_b;//加上关键字mutable使其变成 特殊变量,即使在常函数中,也可以修改这个值,
22 };
23 void test01()
24 {
25     person p;
26     p.showperson();//this指针指向这里
27 }
28 //常对象
29 void test02()
30 {
31     const person p;//在对象前加const,变为常对象,不允许修改指针指向的值
32    // p.m_a = 100;//会报错 因为在常对象里面
33     p.m_b = 100;//mutable 修饰的特殊值,在常对象下也可以修改
34     p.showperson();
35    // p.func();//会显示不兼容,因为函数func中是可以修改指针指向的值的,但是常对象下指针指向的值是不可以修改的
36 }
37 
38 int main()
39 {
40     test01();
41     test02();
42 }
复制代码

 

 

posted on   在野武将  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示