学习类中的const和static类型

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

  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("基类构造函数!
");
 47         strcpy(name, str);
 48         data = 0;
 49     }
 50     inline ~BaseClass()
 51     {
 52         printf("基类析构函数!
");
 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.
", 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("派生类构造函数!
");
120         subname = NULL;
121     };
122 
123     ~DerivedClass()
124     {
125         printf("派生类析构函数!
");
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.
", 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.
", subname, BaseClass::get_max());
165 
166     };
167 };
168 
169 int main()
170 {
171 
172     {
173         // 测试构造函数的顺序
174         printf(">> 构造函数顺序依次是:
");
175         DerivedClass a("Liu");
176         printf("<< 测试结束!

");
177         a.print_string();
178         printf(">> 析构函数顺序依次是:
");
179         // 测试析构函数的顺序
180     }
181     printf("<< 测试结束!

");
182     DerivedClass* b = new DerivedClass("Wang");
183     b->set_sub_name("Jone");
184     b->print_string();
185     // 测试free能否出发析构函数
186     printf(">> 测试free能否触发析构函数:
");
187     free(b);
188     printf("<< 测试结束!

");
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能否触发析构函数:
");
196     delete c;
197     printf("<< 测试结束!

");
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