局部类就是定义在函数内部的类,因为作用域只是在函数内部,所以,所有成员定义必须完整,在Qt的源码中有几处使用了局部类,见博客https://blog.youkuaiyun.com/Master_Cui/article/details/109162220
因为局部类必须定义完整,所以不能在局部类中声明static成员变量,如果定义了static成员变量,要把static成员变量的定义放在类的外部,与局部类必须完整相违背
位域就是含有一定数量二进制位的变量,变量的类型通常应该是无符号整形。位域的声明形式是变量名后跟一个冒号和一个常量表达式,表达式用来指定变量所占的二进制位数
在QT的源码中,有几处使用了该技术。见博客https://blog.youkuaiyun.com/Master_Cui/article/details/109007524
因为变量使用了位域后,变量所占的内存就会变小,位域一般在底层开发中用的比较多。
union uploaddata
{
unsigned char buffer[4];
struct datastr
{
unsigned int audiocount:3;
unsigned int videocount:3;
}data;
};
上述代码中,通过位域表示audio和video的数量,并通过buffer把数据发送给其他模块
三、volatile
如果一个变量是volatile的,那么表示告诉编译器不应该对这样的变量进行优化,这样,每次取volatile变量的值时,都会从内存中进行存取,而不会到缓存中存取。从而保证读取volatile变量值的准确性
一般也是在底层开发中用得较多
四、链接指示
C++有时需要使用其他语言的代码,在C++中,使用链接指示指出其他非C++语言的代码
最常见的是调用C编写的函数,此时就需要用extern "C"
示例
extern "C" {
int strcmp(const char *str1, const char *str2);
char *strcat(char *des, const char* src);
}
上述两个函数就被放在extern "C"的链接指示中,表示是两个C语言函数
因为C语言不支持重载,所以extern "C"中不能有同名函数
extern "C" {
void func();
void func(int );
}

一切C++特有而C中没有的特性都不能加在extern "C"中
五、枚举
枚举就是一系列整形值的集合。当对枚举进行初始化时,要使用枚举成员,即使使用的整形值和枚举成员的值相等,也不能用整形只初始化枚举对象
示例
enum state
{
stop=1,
pause=2,
play=3
};
int main(int argc, char const *argv[])
{
state s1=stop;
s1=3;
}

如果硬要使用整形值初始化枚举对象,那么使用static_cast吧
int main(int argc, char const *argv[])
{
state s1=stop;
s1=static_cast<state>(3);
}
六、定位new
一般的new运算符负责在heap堆中找到一个足以能够满足要求的内存块。new运算符还有另一种变体:定位new运算符(placement new),它能够在分配内存时指定内存的位置。
定位new有以下几种形式

place_address是个地址,指向内存空间,所以,定位new只构造对象并不分配内存
示例
class test
{
public:
test(){}
~test(){}
};
int main(int argc, char const *argv[])
{
char buffer[256];
//char *buffer=new char[256];
char *p=buffer;
int *pi=new(p) int;
cout<<pi<<endl;
p+=sizeof(int);
int *pai=new(p) int[10];
p+=sizeof(int[10]);
cout<<pai<<endl;
test *ptest=new(p) test();
cout<<ptest<<endl;
ptest->~test();
//delete ptest;
//delete buffer;
}

buffer已经在栈上分配内存,所以,buffer在代码块结束后,会自动释放;
如果buffer通过new分配,则需要使用delete释放
对于正常new得到的类对象。delete时会先隐式调用析构函数释放对象,然后调用operator delete释放内存空间
但是对于定位new构造的对象,要显式调用它们的析构函数来销毁对象即可,因为定位new不负责分配内存(析构函数只是销毁对象,并不释放对象的内存)
所以,不能使用delete释放定位new创建的对象的内存,因为delete的这两个动作被拆开了
使用delete会造成错误。

所以,对象需要在buffer释放前,显式的调用析构函数
参考
《C++ Primer》
https://blog.youkuaiyun.com/qq2071114140/article/details/89287373
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出
本文介绍了C++的多种特性,包括局部类,其定义在函数内部,成员定义须完整;位域可减少变量内存占用,常用于底层开发;volatile保证变量读取准确性;链接指示用于调用非C++语言代码;还介绍了枚举、定位new等特性及使用注意事项。
542

被折叠的 条评论
为什么被折叠?



