C++部分关键字总结
作者:SkySuperWL 发布时间:[ 2016/10/20 10:45:55 ] 推荐标签:测试开发技术 C++
9) static只用于类内声明,在类外定义时不能加static。
10) static变量的初始化只能放在源文件中,如果放在头文件中可能会被重复定义。
11) 在对static变量进行初始化时,可以忽略任何存取权限的束缚,例如:
double ClassA::m_a = 0.05; (注意假设ClassA::m_a是private, 则除了在定义static时可以这样写外,其它地方均不得如此)
12) static成员变量不能再类内初始化,必须在类外定义时初始化(在源文件中),但是有个例外,const static成员可以在类内初始化,同时仍必须在类外进行定义,定义时无需加static,无需指定初始值,但必须加const修饰符。[这一条引自C++ Primer,4th Edition, P401,但是上机实验证明,如果已经在类内初始化,则不须在类外定义,否则产生多重定义的变异错误,不知道是不是编译器的问题,我用的是VS2005]
13) static成员可以被继承,父类的static变量和函数在派生类中依然可用,但是受访问控制,而且对static变量来说,派生类和父类中的static变量是共用空间的,这点在利用static变量进行引用计数时要注意。
静态成员函数不能够使用const和volatile修饰。并且静态成员函数只能访问静态成员变量,在静态成员函数中不能使用this。
register
这个关键字命令编译器尽可能的将变量存在CPU内部寄存器中而不是通过内存寻址访问以提高效率。
volatile
volatile的本意是“易变的”,volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码不再进行优化,从而可以提供对特殊地址的稳定访问。
当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被寄存。
volatile int i=10;
int a = i;
。。。//其他代码,并未明确告诉编译器,对i进行过操作
int b = i;
volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据容易出错,所以说volatile可以保证对特殊地址的稳定访问。
const_cast
从类中移除 const、volatile特性。
指向任何对象类型的指针或指向数据成员的指针可显式转换为完全相同的类型(const、volatile 和 __unaligned 限定符除外)。 对于指针和引用,结果将引用原始对象。 对于指向数据成员的指针,结果将引用与指向数据成员的原始(未强制转换)的指针相同的成员。 根据引用对象的类型,通过生成的指针、引用或指向数据成员的指针的写入操作可能产生未定义的行为。
您不能使用 const_cast 运算符直接重写常量变量的常量状态。
const_cast 运算符将 null 指针值转换为目标类型的 null 指针值。
const
const 是一个左结合的类型修饰符,它与其左侧的类型修饰符和为一个类型修饰符。const可以用于定义常量,可以限定函数的引用参数(因为传值的参数根本不用限定),可以限定函数返回值为引用的情况。还有一个用法是修饰类的成员函数。这样情况下,在类内的声明和类外的定义都要加上const。
还有一种情况是,声明类的const成员变量的时候,如何进行初始化。
在这种情况下,由于常量不能修改,所以只能在构造函数的初始化列表中进行复制初始化。如果同时声明为了static时可以在类外进行初始化,但此时不能加static关键字。
virtual
在基类中被定义为virtual的函数,派生类重载该函数不需要再次显示说明该函数是virtual的。
inline, static, constructor三种函数都不能带有virtual关键字。
inline是编译时展开,必须有实体;
static属于class自己的,也必须有实体;
virtual函数基于vtable(内存空间),constructor函数如果是virtual的,调用时也需要根据vtable寻找,但是constructor是virtual的情况下是找不到的,因为constructor自己本身都不存在了,创建不到class的实例,没有实例,class的成员(除了public static/protected static for friend class/functions,其余无论是否virtual)都不能被访问了。
static_cast
该运算符把exdivssion转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
1)用于类层次结构中基类和子类之间指针或引用的转换。
进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
2)用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
3)把空指针转换成目标类型的空指针,把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉exdivssion的const、volitale、或者__unaligned属性。
dynamic_cast
dynamic_cast’只用于对象的指针和引用。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast会检查操作是否有效。也是说,它会检查转换是否会返回一个被请求的有效的完整对象。
检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL。
class Base { virtual dummy() {} }; class Derived : public Base {};
Base* b1 = new Derived; Base* b2 = new Base;
Derived* d1 = dynamic_cast<Derived *>(b1); // succeeds
Derived* d2 = dynamic_cast<Derived *>(b2); // fails: returns 'NULL'
如果一个引用类型执行了类型转换并且这个转换是不可能的,一个bad_cast的异常类型被抛出: 代码:
class Base { virtual dummy() {} }; class Derived : public Base { };
Base* b1 = new Derived; Base* b2 = new Base;
Derived d1 = dynamic_cast<Derived &*>(b1); // succeeds Derived d2 = dynamic_cast<Derived &*>(b2); // fails: exception thrown
reinterpret_cast
reinterpret_cast’转换一个指针为其它类型的指针。它也允许从一个指针转换为整数类型。反之亦然。(译注:是指针具体的地址值作为整数值?)
这个操作符能够在非相关的类型之间转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做任何类型的检查和转换。
如果情况是从一个指针到整型的拷贝,内容的解释是系统相关的,所以任何的实现都不是方便的。一个转换到足够大的整型能够包含它的指针是能够转换回有效的指针的。
说白了是强制类型转换。
class A {}; class B {};
A * a = new A;
B * b = reinterpret_cast<B *>(a);
'reinterpret_cast'像传统的类型转换一样对待所有指针的类型转换。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南