题目一:实现String类中的方法
class String
{
public:
String(char *pstr)
{
_pstr = new char[strlen(pstr)+1];
strcpy(_pstr,pstr);
cout<<this<<endl;
cout<<"String(char *)"<<endl;
}
~String()
{
delete[]_pstr;
_pstr = NULL;
cout<<this<<endl;
cout<<"~String()"<<endl;
}
String(const String &src)//自定义拷贝构造函数
{
_pstr = new char[strlen(src._pstr)+1];
strcpy(_pstr,src._pstr);
cout<<"String(const String &)"<<endl;
}
void operator=(const String &src)//赋值运算符的重载函数
{
if (this == &src)//防止发生自赋值
{
return ;
}
delete[]_pstr;//删除当前对象的_pstr指向的堆空间,防止赋值后找不到此空间发生内存泄漏
_pstr = new char[strlen(src._pstr)+1];//重新开辟堆内存
strcpy(_pstr,src._pstr);
cout<<"operator(const String &)"<<endl;
}
void show()
{
cout<<"the string is "<<_pstr<<endl;
}
private:
char *_pstr;//会发生浅拷贝
};
int main()
{
String string1=("wangiu");
string1.show();
return 0;
}
注意:是否会发生浅拷贝
自定义的拷贝构造函数和赋值运算符的重载函数
题目二:实现Link类
class Link
{
public:
Link()
{
_phead = new Node();//带头节点
}
~Link()
{
Node *pcur = _phead;
while(pcur != NULL)
{
_phead = _phead->_pnext;
delete pcur;
pcur = _phead;
}
}
void insertHead(int val)
{
Node *pnode = new Node(val);
pnode->_pnext = _phead->_pnext;
_phead->_pnext = pnode;
}
void insertTail(int val)
{
Node *pnode = new Node(val);
Node *plast = _phead;
while(plast->_pnext != NULL)
{
plast = plast->_pnext;
}
plast->_pnext = pnode;
}
void deleteNode(int val)
{
Node *ppre = _phead;
Node *pcur = _phead->_pnext;
while(pcur != NULL)
{
if(val == pcur->_data)
{
//删除
ppre->_pnext = pcur->_pnext;
delete pcur;
return;
}
ppre = pcur;
pcur = pcur->_pnext;
}
}
showLink()
{
Node *pcur = _phead->_pnext;
while(pcur != NULL)
{
cout<<pcur->_data<<" ";
pcur = pcur->_pnext;
}
}
private:
class Node
{
public:
Node(int data=0):_data(data),_pnext(NULL){}//初始化列表效率高
int _data;
Node *_pnext;
};//嵌套类 或 内部类
Node *_phead;
};
嵌套类/初始化列表/
题目三:请给出下面对象创建过程中的方法打印(请注明构造和析构对象的名字)
class Test
{
public:
Test(int a=5, int b=5):ma(a), mb(b)
{
cout<<"Test(int)"<<endl;
}
~Test()
{
cout<<"~Test()"<<endl;
}
Test(const Test &src):ma(src.ma), mb(src.mb)
{
cout<<"Test(const Test&)"<<endl;
}
void operator=(const Test &src)
{
ma = src.ma;
mb = src.mb;
cout<<"operator="<<endl;
}
private:
int ma;
int mb;
};
Test t1(10, 10);
int main()
{
Test t2(20, 20);
Test t3=t2;
static Test t4 = Test(30, 30);
t2 = Test(40, 40);
t2 = (Test)(50, 50);
t2 = 60;
Test *p1 = new Test(70, 70);
Test *p2 = new Test[2];
Test *p3 = &Test(80, 80);
Test &p4 = Test(90, 90);
delete p1;
delete []p2;
}
Test t5(100, 100);
运行结果为:
Test t1(10, 10);//构造t1
int main()
{
Test t2(20, 20);//构造t2
Test t3=t2;//t2拷贝构造t3
static Test t4 = Test(30, 30);//临时对象拷贝构造同类型对象,相当于直接构造对象,不生成临时对象
t2 = Test(40, 40);//临时对象(显示生成) operator=给t2赋值 析构临时对象
t2 = (Test)(50, 50);//临时对象(显示生成ma=50 mb=5默认值)注意逗号表达式,取最后一个值 operator=给t2赋值 析构临时对象
t2 = 60;//临时对象 (隐士生成ma=60 mb=5默认值) operator=给t2赋值 析构临时对象
Test *p1 = new Test(70, 70);//new 构造新对象(70,70)
Test *p2 = new Test[2];new //构造两个新对象 不能初始化
Test *p3 = &Test(80, 80);//构造临时对象(80,80) 分号后析构新对象
Test &p4 = Test(90, 90);//构造临时对象(90,90) 临时对象被引用,生命周期变成引用对象的周期
delete p1;//析构p1指向的对象
delete []p2;//两次析构 Test数组中有两个对象
}
Test t5(100, 100);//t5在t1之后构造
4请写出下面程序的打印信息
class Test
{
public:
Test(int a=5):ma(a)
{
cout<<"Test(int)"<<endl;
}
~Test()
{
cout<<"~Test()"<<endl;
}
Test(const Test &src):ma(src.ma)
{
cout<<"Test(const Test&)"<<endl;
}
Test operator=(const Test &src)//注意返回值是Test,返回时生成一个临时对象
{
ma = src.ma;
cout<<"operator="<<endl;
return *this;
}
int GetValue()
{
return ma;
}
private:
int ma;
};
Test GetTestObject(Test &t)
{
int value = t.GetValue();
Test tmp(value);
return tmp;
}
int main()
{
Test t1(20);
Test t2;
cout<<"************************"<<endl;
//t2.operator=()
t2 = GetTestObject(t1);
cout<<t2.GetValue()<<endl;
return 0;
}
运行结果:注意operator=的返回值为Test
operator= 返回值为void的结果
5请解释explicit,volatile,mutable三个关键字
explicit
防止隐式对象的生成,修饰构造函数
volatile
防止编译器对指令顺序进行优化
防止在多线程程序中,线程栈缓存共享变量的副本
mutable
在常成员方法里面可以修改普通成员变量的值