您的位置:首页 > 其它

面题1(类型转换关键字、sizeof(空类型)、复制构造、赋值运算符)

2015-07-12 13:47 393 查看
一、类型转换关键字
1、static_cast
静态转换,编译时使用类型信息执行转换,执行必要的检测,其操作数相对是安全的。应用到类的指针上,它允许子类类转换为父类类型的指针(有效隐式转换),同时,也能够执行相反动作:转换父类为它的子类。
2、dynamic_cast
向下安全转型,用于对象的指针和引用。用于同一继承体系下由上向下移动。如:
Derived* d1=dynamic_cast<Derived>(b1);  //成功
Derived* d2=dynamic_cast<Derived> (b2);  //失败,则不是继承关系,返回0
3、const_cast
操作对象的const属性(添加或移除),如
const int i=5;
int *p;
p=&i; //F
p=(int*)(&i);   //F
p=const_cast<int*>(&i);  //T
long  *p1=const_cast<long*>(&i));  //F 只能在同数据类型间转换
3、reinterpret_cast
转换一个指针为其他类型指针。
A* a=new A;
B* b=reinprepret_cast<B*>(a);

二、sizeof(空类型)
class A{}; A a; 
1、sizeof(a)为1.(VS上运行)
空类型不包含任何信息,本来sizeof应该是0.但我们声明该类型实例时必须在内存占用一定的空间,否则无法使用该实例,具体大小由编译器决定。VS默认为1
2、为类A添加构造和析构是否影响大小?
不影响,这是因为调用构造和析构只要知道这些函数的地址即可,这些函数地址只与类型有关,与类型实例无关。编译器不会因这些函数向类型实例中添加任何消息。
3、如果声明为虚析构函数?
类型中有虚函数,则编译器就会为该类型建立虚函数表。并为每个实例添加一个指向虚函数表的指针。在32机器中,指针占4个字节,sizeof为4,64位机器中为8.
 
三、拷贝构造
首先考虑下面代码的执行
class A
{
public:
A(intn){val=n;}
A(Aother){val=other.val;}  //编译报错 C++不允许复制构造函传值
/*复制构造函数的参数为实例,会导致无限调用递归调用而栈溢出(在复制克制函数内调用复制构造函数)正确做法 A(const A& other);
*/

voidprint(){cout<<val<<endl;}
private:
intval;
};
void main()
{
Aa=10;
Ab=a;  //调用复制构造函数
b.print();
}
四、赋值运算符
考虑为以下类添加一个赋值运算符函数
class String
{
public:
String(char*pData=NULL);
String(constString& str);
~String(void);
private:
char*pData;
};
一个完整可靠的赋值运算函数我们应该考虑以下几点
1、返回对象类型是否为该类型引用
很明显如果返回的不是引用,如void,连续赋值则不可用str3=str2=str1
2、参数是否为常量引用类型
很明显为引用会减少调用复制构造的开销,常量引用可避免传入对象被修改。
3、是否释放实例自身内存
忘记在分配新内存之前释放自身已有空间会引起内存泄漏。
4、判断传入实例是否为自身
在不确定是否为自身时执行3,则释放了自身内存(即传入参数),这也是十分严重的问题。
String& String::operator(const String& str)
{
if(this==&str)
return *this;
delete[] pData;  //分配新空间时未释放可能出现内存泄漏
pData=NULL;
pData=new char[strlen(str.pData)+1];
strcpy(pData,str.pData);
return *this;
}

//(进阶)考虑异常安全性,如果内存分配不足抛出异常,则pData为空指针,容易导致程序崩溃
/*两种方法:1、new分配成功之后再delete当前实例,当分配失败时原实例不会被修改
2、创建临时实例,交换实例
*/
String& String::operator(const String& str)
{
if(this!=&str)
{
String StrTmp=String(str);//String构造中new分配内存,如果分配失败也不会改变原实例状态
char* pTmp=strTmp.pData;
StrTmp.pData=pData; //指向实例之前的内存,出if之后自动delete
pData=pTmp;
}
return *this;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: