Hello,大家好,今天給大家分享兩個C++的小技巧。

在通常情況下,我們定義了一個普通的類,然後就可以建立該類的例項物件,但是在某些情況下,允許使用者任意的建立物件並不是一個好的方法,這時我們就需要限制使用者建立物件。

一般的,物件的建立分兩種方式,一種是在棧上建立物件,另一種是在堆上建立物件,下面我們就從這兩個方面來討論如何限制使用者操作。

1 只允許使用者在堆上建立物件

所謂只允許使用者在堆上建立物件,就是隻允許使用者使用new運算子來建立物件,換句話說要禁止使用者在棧上建立物件。

也許你會想,根據類的建構函式和訪問限制特點,可以將建構函式宣告為私有,但是這樣一來,new運算子也不能訪問構造函數了。

class

X

{

//。。。

};

X

gObject

//line1

void

test

()

{

X

lObject

//line2

X

*

ptr

=

new

X

//line3

}

針對以上程式碼,我們希望“line1”和“line2”編譯錯誤,“line3”編譯正確,那麼我們就需要對類的特殊函式做一些處理。

上面已經說到了,建構函式是不能宣告為私有的,否則也會阻止在堆上建立物件,既然這樣,建構函式就只能宣告為公有了,還有什麼方法可以阻止在棧上建立呢。

我們再仔細想一想,在C++中,有這樣一條規則:當用戶試圖在棧上建立物件時,編譯器會查詢匹配且可以訪問的建構函式和解構函式,如果其中一個無法訪問,編譯就會報錯。

這似乎給了我們一點提示,將解構函式宣告為私有,這樣的話不就可以禁止使用者在棧上建立物件了嗎。

class

X

{

public

X

(){}

void

Delete

()

{

delete

this

}

private

~

X

(){}

};

X

gObject

//line1

void

test

()

{

X

lObject

//line2

X

*

ptr

=

new

X

//line3

}

我們編譯一下,發現符合預期。

但是,馬上下一個問題來了,如果你使用delete來刪除創建出來的物件時,編譯器還是報錯了。

為此,我們可以再編寫一個釋放函式,在函式中呼叫delete運算子,這樣所有的問題就都解決了。

下面是示例程式碼:

class

X

{

public

X

(){}

void

Delete

()

{

delete

this

}

private

~

X

(){}

};

X

gObject

//line1

void

test

()

{

X

lObject

//line2

X

*

ptr

=

new

X

//line3

//。。。

ptr

->

Delete

();

}

好了,大功告成,但是,有一點需要注意,我們在成員函式Delete()中,刪掉了this指標所指物件,這有點像物件的自殺行為,如果該物件再被引用將會報錯,所以請確定不再使用該物件時,再呼叫刪除函式,這個地方一定要注意。

那麼我們可以總結:使解構函式私有化,可以禁止在棧上建立物件。

2 只允許在棧上建立物件

這跟我們上一小節剛好相反,我們需要禁止new運算子建立物件,聰明的同學可能已經想到了,那就是將new和delete運算子宣告為私有的即可。

class

Y

{

public

Y

(){}

private

void

*

operator

new

size_t

size

);

void

operator

delete

void

*

addr

);

};

void

test

()

{

Y

obj

//line1

Y

*

ptr

=

new

Y

//line2

}

編譯一下,正如我們所預想的,“line2”將不能透過編譯,這就阻止了使用者在堆上建立物件,是不是很神奇。

好了,關於今天的分享就到這裡了,儘管這樣的技巧在平時用的不多,但是在某些場景下的確是很好的處理辦法。

例如,如果你正在編寫一個同步鎖或檔案物件等,為了讓鎖自動開啟和釋放或者是讓檔案自動開啟和關閉,你就使該類例項只能在棧上建立,在構造和解構函式中編寫初始化與釋放程式碼,這樣使用者建立的類物件就會自動管理資源,從而你也不必擔心使用者因為忘記釋放資源而造成的種種坑了。

再比如有些工廠函式或類方法,不要求使用者自行new物件,所以可以加限制,這些技巧並不多用,但在某些場景下還是很好用的,可以讓使用者更安全的使用類。等遇到實際問題了,可以往這方面想想,有個思路,平時有個印象即可

最後不要忘記點贊哦,您的支援就是對我最大的鼓勵^_^

歡迎關注微信公眾號-

小豆君Qt分享

C++實用技巧分享,控制物件建立