对编程语言的考核:
- 针对C++概念,如各种关键字,
sizeof()空类型大小为1,即使类内有构造析构函数也一样,但是为虚函数时,会在实例中加入一个指向虚函数表的指针,sizeof为4/8
- 给出已有的程序,分析运行结果
class 复制构造函数A(A other)传入的参数是A的一个实例,形参复制到实参会调用复制构造函数,如果允许复制构造函数传值,会在复制构造函数内调用复制构造函数,永无休止的递归调用导致栈溢出,修改成A& other即可,为避免变动,加入const
- 要求应聘者定义一个类或实现类内成员函数
01赋值运算符函数
考察运算符函数、常量引用、内存泄漏
函数功能
赋值运算符=,对类创建的实例,将a赋给b
要学会想测试案例,可能出现的情况是
1.CMyString a= CMyStrin b一个实例赋给另一个
2.CMyString a=a将实例赋给自己
3.CMyString a=b=c连续赋值
流程
先写类,包括构造函数,析构函数,成员函数先命名
在test中调用
先写类
class CMyString {
public:
CMyString(char* pData = nullptr); //初始化,将字符串赋给该类实例,默认空
CMyString(const CMyString & str); //初始化,将实例A赋给B
~CMyString(void); //析构
CMyString& operator = (const CMyString &str); //赋值运算符重载
void Print(); //打印值
private:
char *m_pData;
};
test测试用例
void test01() {
char* text = "hello world";
CMyString str1(text); //将字符串“”传给CMyString型对象
CMyString str2;
str2 = str1;
}
void test02() {
char* text = "hello world";
CMyString str1(text);
str1 = str1;
str1.Print();
}
void test03() {
char* text = "hello world";
CMyString str1(text);
CMyString str2,str3;
str3 = str2 = str1;
}
对类内构造函数、析构函数定义
//传入pdata字符串,赋给类内变量
CMyString::CMyString(char* pData) {
if (pData == nullptr) {
m_pData = new char[1];
m_pData = '\0';
}
else {
int length = strlen(pData);
m_pData = new char[length + 1];
strcpy(m_pData, pData);
}
}
CMyString::CMyString(const CMyString &str) {
int length = strlen(str.m_pData);
m_pData = new char[length + 1];
strcpy(m_pData, str.m_pData);
}
CMyString::~CMyString() {
delete[] m_pData;
}
nullptr和NULL区别
在C语言中,我们使用NULL表示空指针,NULL实际上是一个void *的指针,C++中不能将void *类型的指针隐式转换成其他指针类型,而又为了解决空指针的问题,所以C++中引入0来表示空指针,0比NULL可以让我们更加警觉,但是我们并没有避免这个问题。这个时候C++ 11的nullptr就很好的解决了这个问题我们在C++ 11中使用nullptr来表示空指针
delete和delete[]区别
delete 释放new分配的单个对象指针指向的内存 delete[] 释放new分配的对象数组指针指向的内存
赋值运算符重载
CMyString& CMyString::operator=(const CMyString & str) {
//如果赋值相同,返回
if (this == &str)
return *this;
//删除原有的
delete[] m_pData;
m_pData = nullptr;
int length = strlen(str.m_pData);
m_pData = new char[length + 1];
strcpy(m_pData, str.m_pData);
return *this;
}
赋值运算符重载的坑
返回值的类型为该类型的引用,如果为void,就不能连续赋值,因为返回自身,类型为该类,且为引用
在函数结束前返回实例自身的引用(*this),只有返回自身的引用,才能连续赋值
传入参数的类型申明为常量引用,如不为常量引用,从形参到实参会调用一次复制构造函数,引用可以避免这种消耗,const不会改变传入的状态。
释放实例自身的内存,如果在分配新内存之前忘了释放,会出现内存泄露
判断传入的参数和当前的实例是否是同一个实例。如果是,则不进行赋值操作。否则在释放时把自身也释放了,就找不到赋值的内容了