学习类中的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("基类构造函数!\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类型相关推荐
- 如何在 C# 中使用 const,readonly,static
平时在开发时经常会用到 const,readonly,static 关键字,可以肯定这些关键词是完全不同的概念,但有时候他们在用法上很相似以至于在场景中不知道选择哪一个,这篇文章我们就来讨论 C# 中 ...
- C#中const和static readonly 的区别
我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等.在多数情况下可以混用. 二者本质的区别在于,const的值是在编译期间确定的,因此只能在 ...
- C++ static、const和static const类型成员变量声明及其初始化
C++ static.const和static const类型成员变量声明及其初始化 const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间. ...
- php中const和static的区别和联系
1.const是类中的常量,类外用define来定义常量 2.const只可以修饰类的属性,不能修饰类的方法,static可以修饰属性,也可以修饰方法 3.const和static都属于类本身,而不属 ...
- const、static型数据在内存中如何存储?(变量存放位置)
const.static型数据在内存中如何存储?(变量存放位置) static int val_a = 1 ; // 初始化的静态变量 int val_b = 2 ; // 全局变量 const in ...
- the different between Const and Static in C++
1.const规定了一个变量在它初始化值之后,值不能再改变,也就是只读. 来看个例子: const测试例子 在这个测试程序里,我试图在初始化变量c的值之后再修改c的值,编译直接报错,告诉我c已经是一个 ...
- C++中的const关键字(zz)
[补充]mutable关键字 有时我们希望类的数据成员即使在const成员函数中,依然是可以修改的,这时就可以把它们声明为mutable来实现.这样的应用,比如记录各种操作的调用次数,这时,即使在co ...
- const和static readonly 区别
我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等. 在多数情况下可以混用. 二者本质的区别在于,const的值是在编译期间确定的,因此只能 ...
- const、static、const staic理解
Table of Contents 1 static的理解 2 const 新自定义类型 p; 则p不可变 3 不可重入函数 4 类的static成员变量 5 类的const成员变量 6 类的stat ...
最新文章
- 添加商品php,php – 为首次购买者添加商品到购物车
- Linux 多应用程序docker自动部署脚本
- 汇编实验1遇到的问题及解决之记录(以及尚未解决的疑惑,大神可以帮帮看看吗)
- ❤️详解腾讯面试❤️
- 学生出勤率平时成绩java_《javaweb应用开发》课程标准.doc
- 【 Grey Hack 】万金油脚本:常见端口修改Password
- 【小聪明】图片消失在另一张图片里
- Linux 之 NTP 服务 服务器
- BZOJ 1066 蜥蜴 最大流
- Python:实现蓝牙通信
- hub设备_五年内任何问题,直接换新,毕亚兹 USB3.0四口HUB分线器体验
- LoRa 信噪比和接收灵敏度
- linux能远程开机么,Linux下如何实现远程开机
- 云免流usb共享电脑_手机怎么使用USB数据线共享PC网络
- 【机器视觉】Halcon 18安装教程
- 如何制作企业在线产品手册?这里有一些简单的方法!
- C++词法记号规则之标识符 关键字 操作符 分隔符 空白符
- 借一道leetcode思考总结map/set的应用及区别
- 基于51单片机数字电压表的设计 仿真、程序、原理图(转发)
- matlab访问脉冲传递函数的分母,笔记:系统模型转换