1、__func__预定义标识符
返回所在函数的函数名,返回类型为const char*类型
例子:
const char* function()
{
return __func__;
}
class Test
{
private:
string name;
public:
Test()
:name(__func__)
{
}
string getName()
{
return name;
}
};
int main(void)
{
cout << function() << endl; //function
Test t;
cout << t.getName() << endl; //Test
return 0;
}
2,宏__cplusplus,这个宏通常被定义为一个整数值,在C++03标准中定义为199711L,在C++11标准中定义为201103L
例子:
int main(void)
{
cout << __cplusplus << endl;
return 0;
}
输出199711
3、long long 类型
long long int 可以表示的范围为:- 9223372036854775808 -- 9223372036854775807
unsigned long long int 表示的最大数字为:18446744073709551615
例子:需要头文件<<>climit>
int main(void)
{
cout << LLONG_MAX << endl;
cout << LLONG_MIN << endl;
cout << ULLONG_MAX << endl;
return 0;
}
4、断言assert:头文件assert
assert(表达式);当表达式为真的时候继续执行下面语句,当表达式为假的时候会自动终止程序运行
例如:
int divide(int a, int b)
{
assert(b != 0);
return a / b;
}
int main(void)
{ int c = divide(15, 3);
cout << c << endl; //5
int d = divide(3, 0); //断言会报出错误,程序会终止
cout << d << endl;
}
但是assert是一个运行时的断言,有的时候我们希望在程序编译的时候做一些断言,那么我们可以考虑静态断言
静态断言static_assert(表达式,错误警告);
表达式通常是一个常量表达式,它返回一个bool类型值,false或者true,错误警告通常是一个字符串,当表达式返回false时执行
例如:
template<typename T1, typename T2>
void _Copy(T1& t1, T2& t2)
{
static_assert(sizeof(t1) == sizeof(t2), "not equal");
memcpy(&t1, &t2, sizeof(t2));
}
int main(void)
{
int a = 4;
double b;
int x;
_Copy(x, a);
cout << x << endl;
_Copy(a, b);
cout << b << endl;
return 0;
}
5、noexcept修饰符
在C++98中我们可以写如下代码来控制一个函数是否会发生异常
void fun()throw(int){ throw 1;} 它允许函数抛出int类型异常
void fun()throw(){} 它表示函数不接受任何参数的异常,也就是说明函数不能抛出异常
在C++11中我们可以利用noexcept修饰符来表示函数是否会发生异常
noexceot修饰符有两种形式
(1)、noexcept
(2)、noexcept(常量表达式):常量表达式会被转换成一个bool类型的值,当这个bool值为true表示函数不会发生异常,如果函数里面发生了异常的时候,系统会调用terminal终止程序的运行,noexcept表示默认为true,不会发生异常
例子:
void Throw() throw(int)
{
throw 1;
}
//在C++11中假如我们不允许一个函数抛出异常,我们可以用到noexcept修饰符,我们可以这样写
void NoThrow()noexcept
{
throw 1;//这个时候我们编译会出现警告信息:“NoThrow”: 假定函数不引发异常,但确实发生了
//表明它不可以抛出异常 ,当它抛出异常时系统调用terminal中断程序的运行
}
void FalseThrow() noexcept(3 == 2)
{
throw 1;
}
int main(void)
{
try
{
Throw();
}
catch (...)
{
cout << "error" << endl;
}
try
{
//NoThrow();
}
catch (...)
{
cout << "NoThrow error" << endl;
}
try
{
FalseThrow();
}
catch (...)
{
cout << "false throw" << endl;
}
return 0;
}
noexcept操作符,通常用于模板
例如
template<typename T>
void fun()noexcept(noexcept(T())){}
这里fun函数是否是一个noexcept函数,将有T()函数是否会抛出异常决定,这里的第二个noexcept就是一个noexcept操作符,当其参数是一个有可能抛出异常的表达式的时候,返回值为false反之为true
6、快速初始化成员变量
在C++11中我们除了可以使用初始化列表来初始化成员变量,也可以使用等号=和花括号{}就地快速初始化成员变量
例如
class A
{
private:
int a = 3;//快速初始化成员变量,在C++98中会报错,但是在c++11中是可以的
char c{ 'V' };
public:
void show()
{
cout << a << endl;
cout << c << endl;
}
};
class B
{
private:
int m_b;
public:
B(int b)
:m_b(b)
{
}
void display()
{
cout << m_b << endl;
}
};
class C
{
private:
B bb{ 10 };
public:
void display()
{
bb.display();
}
};
在C++11中,我们保存了这两种方法,但是这两种方法谁先初始化变量呢,通过实验证明,就地初始化比成员列表初始化快
class Mem
{
public:
int num = 2;
public:
Mem()
{
cout << "default num:" << num << endl;
}
Mem(int i)
:num(i)
{
cout << "num:" << num << endl;
}
};
class Group
{
private:
char val{ 'g' };
Mem a;
Mem b{ 19 };
public:
Group()
{
cout << "default val:" << val << endl;
}
Group(int i)
:val('G'), a(i)
{
cout << "val:" << val << endl;
}
void NumberOfA()
{
cout << "number of a:" << a.num << endl;
}
void NumberOfB()
{
cout << "number of b:" << b.num << endl;
}
};
int main(void)
{
Mem member;
cout << "------" << endl;
Group group;
cout << "------" << endl;
group.NumberOfA();
cout << "------" << endl;
group.NumberOfB();
cout << "------" << endl;
Group group2(7);
cout << "------" << endl;
group2.NumberOfA();
cout << "------" << endl;
group2.NumberOfB();
return 0;
}