c++ 運算子過載、執行緒安全實現單例

耀耀爱学习發表於2024-06-05

一、運算子過載

namespace CalcRect
{
	struct Rect
	{
		Rect(int posX = 0, int posY = 0, int w = 0, int h = 0)
		{
			x = posX;
			y = posY;
			width = w;
			height = h;
		}
		void operator =(const Rect& other)
		{
			x = other.x;
			y = other.y;
			width = other.width;
			height = other.height;
		}

		// 過載運算子"!="
		bool operator != (const Rect& other) const
		{
			return (x != other.x || y != other.y || width != other.width || height != other.height);
		}

		// 過載運算子"=="
		bool operator == (const Rect& other) const
		{
			return (x == other.x && y == other.y && width == other.width && height == other.height);
		}

		Rect operator & (const Rect& other)
		{
			Rect tmp;
			int x1 = (std::max)(x, other.x);
			int y1 = (std::max)(y, other.y);
			tmp.width = (std::min)(x + width, other.x + other.width) - x1;
			tmp.height = (std::min)(y + height, other.y + other.height) - y1;
			tmp.x = x1;
			tmp.y = y1;
			if (tmp.width <= 0 || tmp.height <= 0)
				return Rect();
			return tmp;
		}

		int x; //!< x coordinate of the top-left corner
		int y; //!< y coordinate of the top-left corner
		int width; //!< width of the rectangle
		int height; //!< height of the rectangle
	};

	struct Point
	{
		Point(int posX, int posY)
		{
			x = posX;
			y = posY;
		}
		int x;
		int y;
	};

#define  WINDOW_MAX_COUNT 24
}  

1、運算子過載 void operator =(const Rect& other): 實現賦值操作;
bool operator == (const Rect& other) const 實現判斷兩個rect矩形是否相同返回bool 同時增加const 表明不會更改傳入物件得狀態
同時進行引用傳遞引數:再函式呼叫時傳遞物件得引用 而不是物件得副本
傳遞物件的引用和直接傳遞物件有一些關鍵區別,主要體現在以下幾個方面:

物件的複製行為:
傳遞物件的引用:透過引用傳遞物件,不會觸發物件的複製建構函式,函式內部直接操作的是原始物件。
直接傳遞物件:傳遞物件時,會呼叫物件的複製建構函式建立一個物件的副本,在函式內部操作的是物件的副本,而不是原始物件。
對原始物件修改的效果:
傳遞物件的引用:在函式內部修改物件的狀態會直接反映在原始物件上,因為操作的是同一個物件。
直接傳遞物件:修改的是物件的副本,不會影響原始物件的狀態。
效能和開銷:
傳遞物件的引用:避免了物件的複製,節省了記憶體和時間開銷。
直接傳遞物件:需要建立物件的副本,可能會導致效能損耗,尤其是對於大型物件或頻繁呼叫的情況。
語義上的區別:
傳遞物件的引用:更明確地表示函式會直接操作原始物件,而不是對物件的副本進行操作。
直接傳遞物件:表達的是將物件的副本傳遞給函式,函式操作的是獨立於原始物件的複製。

2.const 作用:

當const 修飾得變數,則表明變數得值是常量 ,不可被修改
當const 修飾得是成員函式 則表示該成員函式,不能改變物件的狀態,同時函式內部 只能呼叫同樣const 修飾得函式
物件的const引用: 表明函式內部 不會修改引用的物件狀態
當函式得引數是常量物件得指標:應該將指標引數宣告為const,這意味著函式不能透過該指標修改物件的值。這種宣告方式可以確保函式內部不會意外地修改指標所指向的物件,提高程式的安全性和可靠性。

二、執行緒安全實現單例

class Pos
	{
	public:
		static Pos& GetInstance() {
			static Pos instance;
			return instance;
		} 
private:
    Pos() {}  // 私有建構函式,確保類外不可直接例項化
    ~Pos() {} // 私有解構函式,防止外部刪除例項

    // 防止複製和賦值
    Pos(const Pos&) = delete;
    Pos& operator=(const Pos&) = delete;
}; 

透過靜態區域性變數 實現c++ 簡單得單例,使得該物件再整個工程當中 只有一份,靜態區域性變數instance的執行緒安全初始化是由C++11標準庫提供的std::call_once來保證的,確保在多執行緒環境下只有一個例項被建立。

Pos(const Pos&) = delete;: 這一行程式碼宣告瞭一個私有的(因為預設是 private)複製建構函式,並將其定義為 delete。這樣一來,當有程式碼企圖使用複製建構函式來建立 Pos 類的物件副本時,編譯器會報錯,從而禁止了物件的複製。

Pos& operator=(const Pos&) = delete;: 這一行程式碼宣告瞭一個私有的賦值運算子過載函式,並將其定義為 delete。這樣一來,當有程式碼嘗試使用賦值運算子來對兩個 Pos類的物件進行賦值操作時,編譯器會報錯,禁止了物件之間的賦值。

相關文章