類和對象階段考試總結

題目一:實現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

在常成員方法裏面可以修改普通成員變量的值




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章