面题1(类型转换关键字、sizeof(空类型)、复制构造、赋值运算符)
2015-07-12 13:47
435 查看
一、类型转换关键字 1、static_cast 静态转换,编译时使用类型信息执行转换,执行必要的检测,其操作数相对是安全的。应用到类的指针上,它允许子类类转换为父类类型的指针(有效隐式转换),同时,也能够执行相反动作:转换父类为它的子类。 2、dynamic_cast 向下安全转型,用于对象的指针和引用。用于同一继承体系下由上向下移动。如:
Derived* d1=dynamic_cast<Derived>(b1); //成功 Derived* d2=dynamic_cast<Derived> (b2); //失败,则不是继承关系,返回03、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; }
相关文章推荐
- [黑马程序员]——java的概述
- PHP设计模式之适配器模式
- ucos II任务管理之三:删除任务
- 通信网络卫星国际会议
- 循环首次适应算法
- jquery.autocomplete.js 文本框自动填充 类似百度搜索引擎效果
- netstat和telnet命令在Windows7中的用法(转载)
- 【NHibernate】配置- sql打印
- [Android] 修改设备访问权限
- 异步任务
- NGUI ——UILabel复制粘贴
- MySQL集群节点、节点组、数据副本、以及分区
- 单词统计
- jquery 判断是否是android或者iOS系统
- 单词统计
- jquery MP3播放器
- 11.Java5的线程锁技术
- [黑马程序员]——Java接口Interface
- 为什么r.java文件中没有button的id
- How use Instruments and display the console in Command Lines applications