剑指offer试题整理1
创始人
2024-01-22 02:50:54

1、定义一个空的类型,里面没有任何成员变量和成员函数。对该类型求sizeof,得到的结果是什么?

答案:1.

为什么不是0?

空类型的示例中不包含任何信息,本来求siezof应该是0,但是当我们声明改类型的实列是时候,它必须再内存中占有一定的空间,否则无法使用这些实例。
对于至少占用多少内存,这由编译器决定。
在Visual Studio中,每个空类型的实例都占用一字节的空间。
在这里插入图片描述

如果在该类型中添加一个构造函数和析构函数,再对该类型求sizeof,得到的结果优势多少?

还是1。
调用构造函数和析构函数只需要知道函数的地址即可,而这些函数的地址只与类型相关,而与类型的示例无关,编译器也不会因为这两个函数而再示例内添加任何额外的信息。
在这里插入图片描述

那添加一个析构函数呢?如果把析构函数标记为虚函数呢?

C++编译器一旦发现一个类型中由虚函数,就会为该类型生成虚函数表,并在该类型的每一个示例中添加一个指向虚函数表的指针。
在32位的机器上,一个指针占4字节,因此求sizeof得到4;如果是在64位的机器,则一个字节占8字节的空间,因此求sizeof得到8。

在这里插入图片描述

2、

给出以下代码,分析编译器运行的结果:
A、编译错误;
B、编译成功,运行时程序崩溃;
C、编译运行正常,输出10;

class A
{
private:int value;
public:A(int n){value = n;}A(A other){value = other.value;}void Print(){std::cout << value << std::endl;}};int _tmain(int argc,_TCHAR *argv[])
{A a = 10;A b = a;b.Print();return 0;
}

在上述代码中,复制构造函数A(A other)传入的参数是A的一个实例。由于是传值参数,我们把形参复制到实参会调用复制构造函数。因此,如果允许复制构造函数传值,就会在复制构造函数内调用复制构造函数,就会形成永无休止的递归调用从而导致栈溢出。因此,C++的标准不允许复制构造函数传值参数,在 Visual Studio和 GCC中,都将编译出错。要解决这个问题,我们可以把构造函数修改为A(const A& other),也就是把传值参数改成常量引用。

在这里插入图片描述
在这里插入图片描述

3、赋值运算符函数

题目:如下为类型CMyString 的声明,请为该类型添加赋值运算符函数。

class CMyString
{
public:CMyString(char *pData = nullptr);	CMyString(const CMyString& str);~CMyString(void);private:char* m_pData;
};

经典解法:

CMyString& CMyString::operator =(const CMyString &str)
{//判断自赋值if(this == &str)return *this;//先释放左值delete[]m_pData;m_pData = nullptr;//开辟右值空间大小m_pData = new char[strlen(str.m_pData) + 1];//拷贝赋值strcpy_s(m_pData,strlen(str.m_pData) + 1,str.m_pData);//返回引用return *this;
}

考虑异常安全性的解法

在经典解法中,我们在分配内存之前先调用了delete 释放了实例 m_pData 的内存。但如果此时的内存不足,导致new char 抛出异常,则 m_pData 将是一个空指针,这样很容易导致程序崩溃。
即,一旦在赋值运算符函数内部抛出一个异常,CMyString的实例不再保持有效的状态,这就违背了安全性原则。

要想在赋值运算符函数中实现异常安全性,有两种方法:
一种简单的办法是我们先用new 分配新内容,再用 delete释放已有的内容。这样只在分配内容成功之后再释放原来的内容,也就是当分配内存失败时我们能确保 CMyString的实例不会被修改。
我们还有一种更好的办法,即先创建一个临时实例,再交换临时实例和原来的实例。下面是这种思路的参考代码:

	CMyString& CMyString::operator =(const CMyString &str){if(this != &str){//创建一个临时实例strTemp,在当前{}结束后,会自动调用自己的析构函数释放相关内存CMyString strTemp(str);//把strTemp.m_pData 和实例自身的m_pData进行交换  当临时变量strTemp析构时,因为进行了交换,所以会释放原来p_Data的内存char* pTemp = strTemp.m_pData; strTemp.m_pData = m_pData;m_pData = pTemp;}return *this;}

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
ps局部放大 放大某个部位的图... 软件类学习建议:边看边练习,可以先收藏后学习。一、使用Ctrl快捷键放大:Ctrl + +缩小:Ct...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
ps局部放大 放大某个部位的图... 软件类学习建议:边看边练习,可以先收藏后学习。一、使用Ctrl快捷键放大:Ctrl + +缩小:Ct...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...