C++中的各种小细节(四)

十五、赋值操作符的右结合性
赋值操作符是从右往左结合的,且其返回值是左值。

十六、sizeof操作符
sizeof操作符的作用是返回一个对象或类型名的长度,注意其返回值类型是size_t类型,
长度的单位是字节。
使用细节:
1:其返回值类型是一个size_t类型,千万不要随意的把返回值赋值给一个int变量。
size_t len ;

2:当作用于表达式时,该函数其实并没有算出该表达式的值,而只是在编译的时候得出了结果值的
类型而已。
len = sizeof(4.0*2 );//作用于表达式
cout<<len<<endl;//输出8

3:sizeof既可以作用于一种类型名,也可以作用于该类型的对象。

struct TS
{
  int ma;
  double mb;
  char mc;
};
	int a =2;
	len = sizeof(a);//作用于对象
	cout<<len<<endl;//输出4
	len = sizeof(TS );//作用于类型名
	cout<<len<<endl;//输出24
	TS * pts;
	len = sizeof(ts);//作用于对象
	cout<<len<<endl;//输出24

4:sizeof也可以作用于指针的解引用,但注意如果 仅仅只是作业于一个指针,将得到指针类型的大小(一般为4个字节)。

	int * p1;
	len = sizeof(*p1);//作用于指针的解引用
	cout<<len<<endl;//输出4
	len = sizeof(*pts );//作用于指针的解引用
	cout<<len<<endl;//输出24

	len = sizeof(pts );//作用于指针
	cout<<len<<endl;//输出4

5:sizeof的另一个特性就是它也是可以作用域一个数组的,其返回值是该元素类型做sizeof的结果乘以数组元素的个数。
同时也就是说通过该方法我们是可以获得任意一个数组的长度的(这个性质很重要)。

	int array[2]= {1,2};
	len = sizeof(array);//作用于数组
	cout<<len<<endl;//输出8

十七、内存耗尽异常
当*存储区被耗尽时,即如果程序用完了所有的内存时,那么new表达式将会
出错,并抛出bad_alloc异常。


十八、typeid操作符--运行时的类型识别
C++中typeid()操作符 主要是用来返回指针或引用所指向的对象的类型,并且在获得类型后可以用其成员操作符
函数进行比较两个类型是否相等,若相等则返回1,即使用type_info类中重载的= =与!=比较两个对象的类型是否相等.
使用该方法需要调用类type_info中重载的= =和!=操作符,其使用方法为typid(object1)= =typid(object2);
如果两个对象的类型相等则反回1,如果不相等则为0。这种使用方法通常用于比较两个带有虚函数的类的对象是否相等
注意typeid()操作符只有在为带有一个或多个虚函数的类返回类型信息时才会支持运行时的动态类型识别,否则对于其他
类型都只是返回其编译时的静态类型信息。

#include<iostream>
using namespace std;
class base {
public:
	virtual ~base(){}

};

class de :public base
{
};

int main()
{
int a = 5;
int *ip = &a;
cout<<typeid(*ip).name()<<endl;//输出int

base ba;
base * pb = new de;

if(typeid(*pb)==typeid(ba))
{
	cout<<"两者类型相同!"<<endl;
}
else
{
	cout<<"两者类型不相同!"<<endl;
}
//输出"两者类型不相同!"
return 0;
}

十九、switch内部的变量定义
由变量的作用域知识可知,对于在switch内部定义定义的任何变量都是从定义它的位置开始有效,一直到switch语句结束,
但是这对于两个case之间定义的变量,将会是一件可怕的事情,因为如果它们被在其他的case里面的调用,则很有可能会是未定义的
变量的,所以C++为switch内部的变量定义定义的一套规则是:"只能在switch结构的最后一个case标号或default标号后面定义变量"。
对于这条规则很好理解:如果在其它地方定义变量则就可能发生上述的未定义异常,但是唯独一个特殊是:在最后一个case
或default中是可以定义变量的,因为在这里面定义的变量是不可能在其他case被引用的,因为其作用域不可能向上扩展。
另外还需注意的一点是:如果真的需要在中间某个case里定义变量,则简单的解决办法是引入块语句,在该块语句中定义变量,
就能防止该变量在其他case里面调用了。

For Example:
	int a = 3;
	//测试switch内部定义变量的规则
	switch (a)
	{   /*
	    *只可以在最后一个case标号或default之后定义变量
	    */
		//int b = 1;//编译出错
	case 1:
		//int m = 1;//编译出错
		break;
	case 2:
		{
		int n = 3;//编译通过
		}
		break;
	case 3:
		int c =3;//编译通过
		cout<<"ss"<<endl;//输出ss
		break;
	}

二十、goto语句
注意在C++中使用goto语句时有一条规则:“goto语句不能跨越变量的定义向前跳转!”
因为如果在跳转后还用到在跳转中跳过的定义变量,则会在编译时报出未定义错误。
For Example:

	cout<<"一"<<endl;
	goto Lable;
	int m = 10; //编译成功!
	Lable:
	cout<<"二"<<endl; 

	cout<<"一"<<endl;
	goto Lable;
	int m = 10; //编译失败!
	Lable:
	cout<<"二"<<endl;
	cout<<m<<endl;//出错:变量m未定义!

C++中的各种小细节(四),布布扣,bubuko.com

C++中的各种小细节(四)

上一篇:Effective C++ 读书笔记(一)


下一篇:Python 学习入门(38)—— @functools模块