上代码,该说的都在代码及注释里:

  1 #include <stdlib.h>
  2 #include <stdio.h>
  3 #include <string>
  4
  5 using namespace std;
  6
  7 class BaseClass
  8 {
  9 protected:
 10     // 普通变量
 11     int data;
 12
 13     // 地址不可变,但内容可变的常量
 14     // 必须在初始值设定项列表中初始化
 15     char* const name;
 16 private:
 17
 18     // 内容不可变常量
 19     // 必须初始值设定项列表中初始化
 20     const int id;
 21
 22     // 类的全部实例共享的变量
 23     // 在任意函数中都可以赋值,但是,这样做不符合其static的意义
 24     // 合理的使用方式是在类外初始化,否则没有合适的赋初值的方式
 25     static int count;
 26
 27     // 类的全部实例共享的常量
 28     // 不能在初始值设定项列表中初始化,初始值设定项列表只能处理非static类型的成员
 29     // 不能在任何函数中赋值
 30     // 所以只能类外初始化
 31     static const int max;
 32 public:
 33     // 关于“是不是所有成员函数都可以声明称虚函数的问题”
 34     // 下面的语句不合法!
 35     // error C2633: “BaseClass”:“inline”是构造函数的唯一合法存储类
 36     // virtual BaseClass(){}
 37
 38     // 关于“const类型的成员变量初始化的问题”
 39     // 下面的语句不合法!
 40     // error C2758: “BaseClass::idx和BaseClass::name””: 必须在构造函数基/成员初始值设定项列表中初始化
 41     // BaseClass(){}
 42
 43     // 合法定义
 44     inline BaseClass(const char* str): id(count++), name((char*)malloc(strlen(str)))
 45     {
 46         printf("基类构造函数!\n");
 47         strcpy(name, str);
 48         data = 0;
 49     }
 50     inline ~BaseClass()
 51     {
 52         printf("基类析构函数!\n");
 53
 54         // 以下语句导致基类析构函数卡住,不知道什么原因,这句话即使放到派生类中,也会导致派生类析构卡住,停止却不报错,很奇怪的现象~
 55         // 无论是new还是malloc的空间,都会卡住
 56         // if (name)
 57         //        free(name);
 58
 59         // 即使用delete也会卡住
 60         // delete name;
 61     }
 62
 63     // 关于“虚函数是否能是static类型的问题”
 64     // 下面的语句不合法!
 65     // error C2216: “virtual”不能和“static”一起使用
 66     // virtual static int doSomething() = 0;
 67
 68     // 合法定义,函数体为const类型
 69     virtual int get_id() const {return id;}
 70     virtual int get_max() const {return max;}
 71
 72     // 合法定义,传入的参数为const类型
 73     virtual void set_data(const int& d){data = d;}
 74
 75     // 关于“const修饰的成员函数的问题”
 76     // 下面的语句不合法!
 77     // error C3490: 由于正在通过常量对象访问“data”,因此无法对其进行修改
 78     // 有const修饰时,类的全部成员变量变成了const类型
 79     // 例如:const char* name 会变成 const char* const name; int data 变成了 const int data;
 80     // virtual void set_data(const int& d) const {data = d;}
 81
 82     // 合法定义
 83     virtual void print_string() const {
 84         printf("My id is %d , my name is %s and my data is %d.\n", id, name, data);
 85     }
 86
 87 };
 88
 89 // 下面的语句不合法!
 90 // error C2720: “BaseClass::cnt”: 成员上的“static ”存储类说明符非法
 91 // static int BaseClass::cnt = 0;
 92
 93 // 合法赋值表达式,必须有类型说明:int,否则不合法
 94 int BaseClass::count = 1;
 95
 96 // 下面的语句不合法!
 97 // error C2373: “max”: 重定义;不同的类型修饰符
 98 // int BaseClass::max = 1024;
 99
100 // 合法赋值表达式,必须同时有const和int
101 const int BaseClass::max = 1024;
102
103 class DerivedClass : public BaseClass
104 {
105 private:
106     char* subname;
107 public:
108     // 由于基类没有默认构造函数,子类必须定义构造函数,而且必须是对应参数及类型的构造函数,否则出现错误:
109     // error C2512: “DerivedClass”: 没有合适的默认构造函数可用
110     // error C2512: “BaseClass”: 没有合适的默认构造函数可用
111     // DerivedClass(){};
112
113     // 下面的语句没有意义,相当于创建的一个临时变量,语句结束即销毁
114     // DerivedClass(const char* str){BaseClass(str);};
115
116     // 合法定义
117     DerivedClass(const char* str):BaseClass(str)
118     {
119         printf("派生类构造函数!\n");
120         subname = NULL;
121     };
122
123     ~DerivedClass()
124     {
125         printf("派生类析构函数!\n");
126
127         // 以下语句会导致delete操作时卡住,不知道为什么,很奇怪~
128         // if (subname)
129         //     free(subname);
130         // subname = NULL;
131
132         // 下面的语句同上,莫名其妙的卡住
133         // delete subname;
134
135     }
136
137     void set_sub_name(const char* str)
138     {
139         if(subname)
140             free(subname);
141         subname = new char[strlen(str)];
142         strcpy(subname, str);
143     }
144
145     void print_string() const
146     {
147         // 下面的语句不合法!
148         // 因为id是private类型,不能被子类访问
149         // 而protected类型可以,例如name和data
150         // error C2248: “BaseClass::id”: 无法访问 private 成员(在“BaseClass”类中声明)
151         // printf("My id is %d , my name is %s and my data is %d.\n", id, name, data);
152
153         // 下面的语句不合法
154         // 因为有const修饰的函数无法调用派生类和基类的非const类型的函数
155         // error C2662: “BaseClass::set_data”: 不能将“this”指针从“const DerivedClass”转换为“BaseClass &”
156         // set_data(1);
157
158         // 合法调用
159         BaseClass::print_string();
160
161         // 合法调用
162         // const修饰的函数只能调用派生类和基类的const函数,下面的Base::get_id()便是一个有const修饰的函数
163         // 这是派生类的const函数访问基类的private函数的唯一方法,访问他们的const类型的get函数,但是显然const类型的函数无法修改private类型的变量,也无法修改其他类型的变量
164         printf("I'm a DerivedClass, my subname is %s and I can see max = %d.\n", subname, BaseClass::get_max());
165
166     };
167 };
168
169 int main()
170 {
171
172     {
173         // 测试构造函数的顺序
174         printf(">> 构造函数顺序依次是:\n");
175         DerivedClass a("Liu");
176         printf("<< 测试结束!\n\n");
177         a.print_string();
178         printf(">> 析构函数顺序依次是:\n");
179         // 测试析构函数的顺序
180     }
181     printf("<< 测试结束!\n\n");
182     DerivedClass* b = new DerivedClass("Wang");
183     b->set_sub_name("Jone");
184     b->print_string();
185     // 测试free能否出发析构函数
186     printf(">> 测试free能否触发析构函数:\n");
187     free(b);
188     printf("<< 测试结束!\n\n");
189     b = NULL;
190
191     // 测试delete能否触发析构函数
192     DerivedClass* c = new DerivedClass("Zhao");
193     c->set_sub_name("Mike");
194     c->print_string();
195     printf(">> 测试delete能否触发析构函数:\n");
196     delete c;
197     printf("<< 测试结束!\n\n");
198     c = NULL;
199
200     // 合法,释放堆中的空间
201     int* arr1 = new int[10];
202     free(arr1);
203
204     // 语法合法,但执行非法,通过free释放栈中的空间
205     // int arr2[10] = {0};
206     // free(arr2);
207
208     // 语法合法,但执行非法,通过free释放常量区的空间
209     // char* arr3 = "Hello !";
210     // free(arr3);
211
212     getchar();
213     return 0;
214 }

输出结果是:

>> 构造函数顺序依次是:
基类构造函数!
派生类构造函数!
<< 测试结束!My id is 1 , my name is Liu and my data is 0.
I'm a DerivedClass, my subname is (null) and I can see max = 1024.
>> 析构函数顺序依次是:
派生类析构函数!
基类析构函数!
<< 测试结束!基类构造函数!
派生类构造函数!
My id is 2 , my name is Wang and my data is 0.
I'm a DerivedClass, my subname is Jone and I can see max = 1024.
>> 测试free能否触发析构函数:
<< 测试结束!基类构造函数!
派生类构造函数!
My id is 3 , my name is Zhao and my data is 0.
I'm a DerivedClass, my subname is Mike and I can see max = 1024.
>> 测试delete能否触发析构函数:
派生类析构函数!
基类析构函数!
<< 测试结束!

转载于:https://www.cnblogs.com/zanzan101/p/3342023.html

学习类中的const和static类型相关推荐

  1. 如何在 C# 中使用 const,readonly,static

    平时在开发时经常会用到 const,readonly,static 关键字,可以肯定这些关键词是完全不同的概念,但有时候他们在用法上很相似以至于在场景中不知道选择哪一个,这篇文章我们就来讨论 C# 中 ...

  2. C#中const和static readonly 的区别

    我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等.在多数情况下可以混用. 二者本质的区别在于,const的值是在编译期间确定的,因此只能在 ...

  3. C++ static、const和static const类型成员变量声明及其初始化

    C++ static.const和static const类型成员变量声明及其初始化 const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间. ...

  4. php中const和static的区别和联系

    1.const是类中的常量,类外用define来定义常量 2.const只可以修饰类的属性,不能修饰类的方法,static可以修饰属性,也可以修饰方法 3.const和static都属于类本身,而不属 ...

  5. const、static型数据在内存中如何存储?(变量存放位置)

    const.static型数据在内存中如何存储?(变量存放位置) static int val_a = 1 ; // 初始化的静态变量 int val_b = 2 ; // 全局变量 const in ...

  6. the different between Const and Static in C++

    1.const规定了一个变量在它初始化值之后,值不能再改变,也就是只读. 来看个例子: const测试例子 在这个测试程序里,我试图在初始化变量c的值之后再修改c的值,编译直接报错,告诉我c已经是一个 ...

  7. C++中的const关键字(zz)

    [补充]mutable关键字 有时我们希望类的数据成员即使在const成员函数中,依然是可以修改的,这时就可以把它们声明为mutable来实现.这样的应用,比如记录各种操作的调用次数,这时,即使在co ...

  8. const和static readonly 区别

    我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等. 在多数情况下可以混用. 二者本质的区别在于,const的值是在编译期间确定的,因此只能 ...

  9. const、static、const staic理解

    Table of Contents 1 static的理解 2 const 新自定义类型 p; 则p不可变 3 不可重入函数 4 类的static成员变量 5 类的const成员变量 6 类的stat ...

最新文章

  1. 添加商品php,php – 为首次购买者添加商品到购物车
  2. Linux 多应用程序docker自动部署脚本
  3. 汇编实验1遇到的问题及解决之记录(以及尚未解决的疑惑,大神可以帮帮看看吗)
  4. ❤️详解腾讯面试❤️
  5. 学生出勤率平时成绩java_《javaweb应用开发》课程标准.doc
  6. 【 Grey Hack 】万金油脚本:常见端口修改Password
  7. 【小聪明】图片消失在另一张图片里
  8. Linux 之 NTP 服务 服务器
  9. BZOJ 1066 蜥蜴 最大流
  10. Python:实现蓝牙通信
  11. hub设备_五年内任何问题,直接换新,毕亚兹 USB3.0四口HUB分线器体验
  12. LoRa 信噪比和接收灵敏度
  13. linux能远程开机么,Linux下如何实现远程开机
  14. 云免流usb共享电脑_手机怎么使用USB数据线共享PC网络
  15. 【机器视觉】Halcon 18安装教程
  16. 如何制作企业在线产品手册?这里有一些简单的方法!
  17. C++词法记号规则之标识符 关键字 操作符 分隔符 空白符
  18. 借一道leetcode思考总结map/set的应用及区别
  19. 基于51单片机数字电压表的设计 仿真、程序、原理图(转发)
  20. matlab访问脉冲传递函数的分母,笔记:系统模型转换

热门文章

  1. #20145238荆玉茗《网络对抗》-逆向及Bof进阶实践
  2. JVM 1.类的加载、连接、初始化
  3. fedora常见问题和解决方案
  4. 容器 vector :为何要有reserve
  5. 博客园与啊里云的故障假设:高需与低配(补充了降频论)
  6. [转]七大.NET开源框架
  7. IIS弹出服务没有及时响应启动或控制请求
  8. (转载)为什么欧美拿金牌不感谢祖国
  9. R语言:使用REmap绘制超炫酷的地图
  10. bps计算机,bps指的是计算机的什么