C++11中__func__,__cplusplus,long long类型,static_assert,noexcept,快速初始化成员变量用法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yp18792574062/article/details/74781697

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>

扫描二维码关注公众号,回复: 5473967 查看本文章
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;
}












猜你喜欢

转载自blog.csdn.net/yp18792574062/article/details/74781697