auto
作用:推断变量类型
注意点:
1.必须赋初值
2.函数和模板参数不能被声明为auto
3.因为auto是一个占位符,并不是一个他自己的类型,因此不能用于类型转换或其他一些操作,如sizeof和typeid
4.定义在一个auto序列的变量必须始终推导成同一类型
vector<int>numVec
auto it=num.begin() it的类型为vector<int>::iterator
const_cast
作用:去掉const属性
语法:const_cast<type>(object)
用法:
- 常量指针转变为非常量指针
const int a=10;
int*p=const_cast<int*>(&a);
*p=100;
cout<<*p<<a<<endl;//100 10
- 常量引用转变为非常量引用
int a=10;
const int &b=a;
int c=const_cast<int&>(b);
c=200;
cout<<c<<b<<c<<endl; 200 10 10
注意:const_case只能转换指针或引用,即上述2种转换
dynamic_cast
作用:将一个类型转化为另外一种类型,并且在执行运行时时检查它保证它的合法性
语法:dynamic_cast<type>(object)
dynamic详细
注意:
当转换为指针,转换失败,返回空指针;
转换为引用,转换失败,会抛出异常。
enum
作用:创建一个包含多个名称元素的名称表
语法:enum color{red, orange, yellow, green, blue, indigo, violet}
注意:
- 序号从0开始;
enum color{red, orange, yellow, green, blue, indigo, violet}
//red=0,orange=1,yellow=2,green=3,blue=4,indigo=5,violet=6
- 定义枚举类型时为部分或全部枚举常量指定整数值,在指定值之前的枚举常量仍按默认方式取值,而指定值之后的枚举常量按依次加1的原则取值;枚举值可以重复
enum fruit_set {apple, orange, banana=1, peach, grape}
//枚举常量apple=0,orange=1, banana=1,peach=2,grape=3
3.枚举常量只能以标识符形式表示,而不能是整型、字符型等文字常量 ,以下定义非法
enum letter_set {'a','d','F','s','T'}; //枚举常量不能是字符常量
enum year_set{2000,2001,2002,2003,2004,2005}; //枚举常量不能是整型常量
4.枚举变量可以直接输出,但不能直接输入cout >> color3; //非法
5.不能直接将常量赋给枚举变量。如: color1=1; //非法
6.不同类型的枚举变量之间不能相互赋值。如: color1=color3; //非法
extern
作用:告知编译器变量在当前范围之外声明过了.被extern语句描述过的变量将分派不到任何空间,因为他们在别的地方被定义过了。extern语句频繁的用于在多个文件之间的跨范围数据传递.
语法:extern type a
注意:
1.一个文件中定义了变量和函数, 在其他文件中要使用它们, 可以有两种方式:
-
使用头文件,然后声明它们,然后其他文件去包含头文件
-
在其他文件中直接extern
2.extern"C"
C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时无法找到对应函数的情况.
- 用C 开发了一个DLL 库,为了能够让C ++语言也能够调用你的DLL 输出(Export) 的函数,你需要用extern “C” 来强制编译器不要修改你的函数名。所有函数声明放在some code的位置
#ifdef __cpluscplus
extern "C" {
#endif
//some code
#ifdef __cplusplus
}
#endif
- 如果这个模块已经存在了,可能是公司里的前辈写的,反正就是已经存在了,模块的.h文件中没有extern "C"关键字,这个模块又不希望被改动的情况下,可以这样,在你的c++文件中,包含该模块的头文件时加上extern “C”, 如下
extern "C" {
#include "test_extern_c.h"
}
- 上面例子中,如果仅仅使用模块中的1个函数,而不需要include整个模块时,可以不include头文件,而单独声明该函数,像这样:
extern "C"{
int ThisIsTest(int, int);
}
- 不要把变量定义放入.h文件,这样容易导致重复定义错误。
- 尽量使用static关键字把变量定义限制于该源文件作用域,除非变量被设计成全局的。
也就是说 - 可以在头文件中声明一个变量,在用的时候包含这个头文件就声明了这个变量
inline
作用:关键字inline请求编译器给一个函数扩展空间,它向这个函数发出一条插入代码的call
注意:函数里面有static 数据, 循环, switches, 或者是递归的时候不给予内联.当一个函数声明包含在一个类声明里面时,编译器会尝试的自动把函数内联
mutable
作用:忽略所有const 语句,一个属于const对象的mutable 成员可以被修改
namespace
作用:创建一个新的空间
语法:namespace name { declaration-list; }
使用:明确说明或者使用using关键字
namespace CartoonNameSpace {
int HomersAge;
void incrementHomersAge() {
HomersAge++;
}
}
int main() {
//明确使用 或者前面加上using namespace CartoonNameSpace ;
CartoonNameSpace::HomersAge = 39;
CartoonNameSpace::incrementHomersAge();
cout << CartoonNameSpace::HomersAge << endl;
}
static_cast
作用:
- 强制类型转换,显示转换,编译器隐式执行的任何类型转换都可以由static_cast来完成(int转float,double转char),明确告诉编译器该精度损失是知情的
- 用于基类与派生类指针或引用类型之间的转换,但不做运行时的检查,不如dynamic_cast安全,dynamic_cast在执行效率上比static_cast要差一些。
用法:
class ANIMAL;//基类
class DOG;//派生类
//派生转基类是安全的,基类转派生类不一定是安全的
//基类指针转派生类指针,且该基类指针指向基类对象的,转换失败
ANIMAL*an1=new ANIMAL;
DOG*dog=static_cast<DOG*>(an1);
//dog->outputType();错误,ANIMAL类型的指针不能调用DOG的outputType方法
//基类指针转为派生类指针,且该基类指针指向派生类对象
ANIMAL * ani3 = new DOG;
DOG* dog3 = static_cast<DOG*>(ani3);
dog3->OutPutname(); //正确
//派生类指针转为基类指针
DOG *dog2= new DOG;
ANIMAL *ani2 = static_cast<DOG*>(dog2);
ani2->OutPutname(); //正确,结果输出为大黄
#template
作用:创建一个对未知数据类型的操作的函数模板
语法:
template <class data-type> return-type name( parameter-list ) {
statement-list;
}
template <typename data-type> return-type name( parameter-list ) {
statement-list;
}
//例子:
template<class T> void swap(T& t1, T& t2);
template<typename T> void swap(T& t1, T& t2);