"只定义了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++的抽象类,你是无法创建一个实例的。