c++類的拷貝構造函數、隱式轉換、重載的賦值操作符的一些分析和實例

1. 隱式轉換和拷貝構造之間的一點實例分析

#include <stdio.h>
#include <iostream>
#include <vector>
#include <map>
using namespace std;

class A
{
public:
	A(int i): m_a(i) 
	{
		printf("constructor\n");
	}

	A(const A &a)
	{
		printf("copy constructor\n");
		m_a = a.m_a;
	}

protected:
	int m_a;
};

int _tmain(int argc, _TCHAR* argv[])
{
        A a = 1;
        getchar();
	return 0;
}
運行結果是:

constructor
分析:從以上結果可以發現通過隱式轉換A a = 1相當於執行了A a(1)。這與我預測的先把1轉換爲一個A類型的臨時變量調用一次構造函數,然後臨時變量再賦值給a調用一次拷貝構造函數的想法不一樣,出現這種結果應該是編譯器編譯的時候發現存在隱式轉換於是直接把A a = 1處理成A a(1)了,這樣可以省掉一些中間不必要的開銷。


2. 重載的賦值操作符、拷貝構造函數與隱式轉換

#include <stdio.h>

class A
{
public:
	A(int i): m_a(i) 
	{
		printf("constructor\n");
	}

	A(const A &a)
	{
		printf("copy constructor\n");
		m_a = a.m_a;
	}

	A& operator = (const A& a)
	{
		printf("operator =\n");
		this->m_a = a.m_a;
		return *this;
	}

protected:
	int m_a;
};

int _tmain(int argc, _TCHAR* argv[])
{
	A a(1);
	a = 1;
	getchar();
	return 0;
}

運行結果如下:

constructor
constructor
operator =
分析:首先是定義a的時候調用了一次構造函數,第二次構造函數是由於 a = 1的時候因爲隱式轉換把1轉換爲A類型的臨時變量導致的,最後是賦值操作


3. 如何避免隱式轉換

#include <stdio.h>

class A
{
public:
	A(int i): m_a(i) 
	{
		printf("constructor\n");
	}

	A(const A &a)
	{
		printf("copy constructor\n");
		m_a = a.m_a;
	}

protected:
	int m_a;
};

int _tmain(int argc, _TCHAR* argv[])
{
	A a = 1;
	getchar();
	return 0;
}

分析:通過給引發隱式轉換的構造函數加上explicit關鍵字來阻止隱式轉換的發生,上面代碼編譯不能通過:error C2440: “初始化”: 無法從“int”轉換爲“A”。


4.重載+操作符:

#include <stdio.h>

class A
{
public:
	explicit A(int i) : m_a(i)
	{
		printf("constructor\n");
	}

	A(const A &a)
	{
		printf("copy constructor\n");
		m_a = a.m_a;
	}

	A& operator = (const A& a)
	{
		printf("operator =\n");
		this->m_a = a.m_a;
		return *this;
	}

	A operator + (const A& a)
	{
		printf("Generic\n");
		return A(this->m_a + a.m_a);
	}
	
	A operator + (const int a)
	{
		printf("int\n");
		return A(this->m_a + a);
	}

	double operator + (const double a)
	{
		printf("double\n");
		return this->m_a + a;
	}

protected:
	int m_a;
};

int _tmain(int argc, _TCHAR* argv[])
{
	A a(1);
	printf("\n");
	A b = a + 1;
	printf("\n");
	double c = a + 2.0;    //出錯:double c = a + 2;
	printf("\n");
	A d = a + b;
	getchar();
	return 0;
}

運行結果如下:

constructor

int
constructor

double

Generic
constructor
分析:從以上結果可知,類A可以重載多個operator + 操作,傳入參數和返回值可以根據自己的需要去設置。



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