題目一:實現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
在常成員方法裏面可以修改普通成員變量的值