C++部分关键字总结
作者:SkySuperWL 发布时间:[ 2016/10/20 10:45:55 ] 推荐标签:测试开发技术 C++
auto
C++11引入的auto关键字实现类型退到,通过这个关键字不仅能方便地获取复杂的类型,而且还能简化书写,提高编码效率。
auto x = 5; //OK
auto pi = new auto(1); //OK
const auto *v = &x, u = 6; //OK
auto int r; //error:auto不在表示存储类型指示符,这也是新更改的特性
auto str; //error:无法推导出str类型
Note:v与u的推导需要注意两个小地方
1)虽然经过前面const auto *v = &x 的推导,auto的类型可以确定为int,但是u仍然必须要写后面的“=6”,否则编译不通过。
2)U的初始化不能使编译器推导产生二义性。ep:u = 6改为 u = 6.0, 编译器会报错。
auto并不代表实际的类型声明,仅仅是一个类型声明的“占位符”。
使用auto声明的变量必须马上初始化,让编译器推导出它的实际类型,并在编译时将auto占位符替换为真正的类型。
在C++11之前,auto 表示“具有自动存储期的局部变量”,不过其实它在这方面的作用不大,auto int i = 1; 对这个我们再熟悉不过了。不写auto也是一样的效果是为了跟static int j = 1;区分开来而已。
auto推导可以和指针,引用结合起来使用,还可以带上const,volatile限定符。
int x = 1;
const auto e =x; //const int
auto f = e; //int
const auto& g = x; //const int&
auto& h= g; //const int&
从上面的例子不难看出:
1)当不声明为指针和引用时,auto的推导结果和初始化表达式抛弃引用和CV限定符后类型一致。
2)当声明为指针或者引用时,auto的推导结果将保持初始化表达式的cv属性。
decltype
decltype关键字,用来在编译时推导出一个表达式的类型。语法格式:
decltype(exp)
int x = 0;
decltype(x) y = 1; // y->int
const int& i = x; //i->const int &
decltype(i) j = y; //j->const int &
const decltype(y) * p =&z; // p->const int *
decltype(x) * pi = &x; //*pi->int
decltype(pi)* pii = &pi //*pii->int *
从上面的例子不难看出decltype的推导规则:
1)exp是标示符,雷访问表达式,decltype(exp)和exp类型一致
2)exp是函数调用,decltype(exp)和返回值的类型一致
3)若exp是一个左值,则decltype(exp)是exp类型的左值引用,否则和exp类型一致。
decltype与引用
int i = 42;
int *p = &i:
decltype(*p) c;//error:c是int &必须初始化
所以如果表达式是解引用的操作,则decltype得到引用类型。解引用可以得到指针所指的对象,而且还能给这个对象赋值。
decltype与auto还有一个重要的区别:decltype与表达式的形势密切相关。对于decltype所用的表达式来说,如果变量名加上了一对括号,则得到的类型与不加括号是不一样的。也是说decltype使用一个不加括号的变量,则得到的结果是该变量的类型。而加上一层或者多层括号的是作为一个特殊的左值表达式。得到的是引用类型。
decltype(i) = e; //OK
decltype((i)) = e; //error:e为引用类型必须初始化
explicite
explicit使用注意事项:
*explicit 关键字只能用于类内部的构造函数声明上。
*explicit 关键字作用于单个参数的构造函数。
在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。
explicit关键字只能用于类内部的构造函数声明上。在类的定义体外部所做的定义上不能再重复它。
如果一个类或结构存在多个构造函数时,explicit 修饰的那个构造函数是默认的
当构造函数被声明为explicit时,编译器将不使用它作为转换操作符。
explicit 关键字作用于单个参数的构造函数。
通常,除非有明显的理由想要定义隐式转换,否则,单形参构造函数应该为explicit。
inline
1) inline表示内联,即在函数调用出将函数内联地展开。
2) inline既可以出现在类定义内部,也可以出现在外部。当在外部出现时必须定义在类定义的头文件中,因为调用函数时需要看到函数是什么样子。
3)inline修饰的函数是在编译时期。
constexptr
这个constexptr函数指能用于常量表达式的函数。定义为constexptr的函数的方法与其它函数类似。不过要遵循:函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句:
constexptr int new_sa() {return 42;}
constexptr int foo = new_sa();//OK
我们把new_sz定义成无参数的constexpr函数。因为编译器能在程序编译时验证new_sz函数的返回的是常量表达式,所有可以用new_sz函数初始化constexpr类型的变量foo。
执行该初始化任务时,编译器把对constexpr函数的调用替换成其结果值。为了能在编译过程中随时展开,constexpr函数被隐式的定义为内联函数。
constexpr函数体内也可以包含其他语句,只要这些语句在运行时不执行任何操作行。例如,constexpr函数中可以有空语句、类型别名以及using声明。
我们允许constexpr函数的返回值并非一个常量:
//如果arg是常量表达式,则scale(arg)也是常量表达式
constexpr size_t scale(size_t cnt) {return new_sz()*cnt;}
当scale的实参是常量表达式时,它的返回值也是常量表达式:反之则不然:
int arr[scale(2)]; //正确:scale(2)是常量表达式
int i=2; //i不是常量表达式
int a2[scale(i)]; //错误:scale(i)不是常量表达式
如上例所示,当我们给scale函数传入一个形如字面值2的常量表达式时,它的返回类型也是常量表达式。此时,编译器用相应的结果值替换对scale函数的调用。
如果我们用一个非常量表达式调用scale函数,比如int类型的对象i,则返回值是一个非常量表达式。当把scale函数用在需要常量表达式的上下文中时,由编译器负责检查函数的结果是否符合要求。如果结果恰好不是常量表达式,编译器将发出错误信息。
constexpr函数不一定返回常量表达式
我也有点云里雾里的。大家看着理解吧。
把内联函数和constexpr函数放在头文件内
和其他函数不一样,内联函数和constexpr函数可以再程序中多次定义。毕竟,编译器要想展开函数仅有函数声明是不够的,还需要函数的定义。不过,对于某个给定的内联函数或者constexpr函数来说,它的多个定义必须定义一致。基于这个原因,内联函数和constexpr函数通常定义在头文件中。
friend
1) 类的friend函数可以访问类的private和protected成员。
2) friend关系不能继承,基类的友元对子类的成员没有特殊访问权限,如果基类被授予友元关系,则只有基类具有特殊访问权限,其派生类不能访问授予友元关系的类。
3) 派生类的friend函数可以访问派生类的一切变量,包括从基类继承下来的protected域中的变量,但对父类来说它不是friend。也是说friend和类本身的访问权是。
4) friend关键字只能出现在类定义内部,不可出现在外部。
#include
#include
class Point
{
public:
Point(double xx, double yy) { x=xx; y=yy; }
void Getxy();
friend double Distance(Point &a, Point &b);
private:
double x, y;
};
double Distance(Point &a, Point &b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx*dx+dy*dy);
}
static
在C++中此关键字用途更多。
1) static类成员属于整个类,不属于某个类对象。
2) static成员遵循正常的公有/私有访问规则。
3) 对于public static成员可以通过类名或对象名访问,对于private static成员则不可,须按照正常private成员访问规则进行访问。
(4) static成员函数可以访问static成员函数和变量,不可访问非static成员和函数,因为static成员是类的,而非static是对象的,类的产生先于对象,怎么能在对象为产生之间调用它的数据呢。
5) 非static成员函数既可以访问static成员又可以访问非static成员。
6) 可以通过类名直接调用public static成员,或者通过对象名、引用或指针间接调用。注意此处指的是public static成员,不是private。
7) static成员函数没有this指针,因为this指向的是对象。
8) static成员函数不能声明为const或虚函数,因为此二者都是针对对象而言,此外static函数实际上是”加上了访问控制的全局函数”,全局函数当然没有虚函数。但是static变量可以声明为const。
相关推荐
更新发布
功能测试和接口测试的区别
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