"只定义了protected构造函数的类也是抽象类。"那么对于“禁止创建栈对象”这个问题,本身抽象类就不能实例化,是否问题本身就没有意义了呢?
业精于勤,荒于嬉;行成于思,毁于随。
先理清一下“抽象類別”,要指出的是:抽象類別不能被實例化,但不能被實例化的類別不一定就是抽象類別。如:
class A { private: A(){ } A(A&) { } };
這不叫抽象類,因為它沒有包含純虛函數。如果想用類別名稱來宣告一個物件是編譯不過的,這就是你問題中提到的「禁止創建棧物件」。 但這樣的類別是有用的,給它添加點代碼,例如
class A { public: static A& getInstance(){ static A a; return a; } void hello() { } private: A(){ } A(A&) { } };
雖然在類A外不能聲明對象,但在A自己裡面完全可以,然後別人可以這樣使用:
A::getInstance().hello();
這就是著名的「單例模式」。
在C++裡,抽象類別的定義就是包含有純虛函數的類,例如
class Abstract { virtual void foo() = 0; };
所謂的抽象類別不能實例化對象,指的是
Abstract a; Abstract *pA = new Abstract();
在編譯的時候都會報錯。
而「只定義了protected建構子的類別也是抽象類別」這個話其實是不對的,或者說如果這句話是對的,那麼這裡的抽象類別就是一個廣義的抽象類,也就是說這裡的抽象類別借鏡了Java的說法,就是不能實例化物件的類別認為就是「抽象類別」。 因為抽象類別的產生就是為了描述介面的,而如果只是建構子不是公有的類,其存在的意義可能並不是為了精準描述介面的。 具體的例子可以參考jk_v1的單例描述,對於C++的抽象類,你是無法建立一個實例的。
先理清一下“抽象類別”,要指出的是:抽象類別不能被實例化,但不能被實例化的類別不一定就是抽象類別。如:
這不叫抽象類,因為它沒有包含純虛函數。如果想用類別名稱來宣告一個物件是編譯不過的,這就是你問題中提到的「禁止創建棧物件」。
但這樣的類別是有用的,給它添加點代碼,例如
雖然在類A外不能聲明對象,但在A自己裡面完全可以,然後別人可以這樣使用:
這就是著名的「單例模式」。
在C++裡,抽象類別的定義就是包含有純虛函數的類,例如
所謂的抽象類別不能實例化對象,指的是
在編譯的時候都會報錯。
而「只定義了protected建構子的類別也是抽象類別」這個話其實是不對的,或者說如果這句話是對的,那麼這裡的抽象類別就是一個廣義的抽象類,也就是說這裡的抽象類別借鏡了Java的說法,就是不能實例化物件的類別認為就是「抽象類別」。 因為抽象類別的產生就是為了描述介面的,而如果只是建構子不是公有的類,其存在的意義可能並不是為了精準描述介面的。
具體的例子可以參考jk_v1的單例描述,對於C++的抽象類,你是無法建立一個實例的。