如何利用c++编写不能被继承但可以在类外定义对象的类
Posted 积少成多
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何利用c++编写不能被继承但可以在类外定义对象的类相关的知识,希望对你有一定的参考价值。
1 #include <iostream> 2 #include<string> 3 #include<map> 4 #include<vector> 5 #include"thread_pool.h" 6 7 8 using namespace std; 9 template<class T> 10 class base{ 11 friend T;/// friend class 12 private: 13 base(){} 14 ~base(){} 15 }; 16 17 class derived : public virtual base<derived> 18 { 19 public: 20 derived(){} 21 void show(){ 22 cout<<"can be instanced,but can not be inherited"<<endl; 23 } 24 ~derived(){} 25 }; 26 27 class dderived : public derived{ 28 public: 29 dderived(){} 30 ~dderived(){} 31 }; 32 33 34 35 int main() 36 { 37 cout << "Hello world!" << endl; 38 derived d; 39 d.show(); 40 return 0; 41 }
只要把类A的构造函数和析构函数定义为private类型,那么就不能在类A外部建立类的对象,也不能将类A作为基类进行继承。
因为如果继承,建立对象的时候调用基类的构造函数,因为是private的,所以派生类调用基类构造函数的时候,将会链接失败--》不能继承,但是我们也就不能在类外定义对象了。
-------------
class base{
friend T;/// friend class
private:
base(){}
~base(){}
};
class derived : public virtual base<derived>
{
public:
derived(){}
void show(){
cout<<"can be instanced,but can not be inherited"<<endl;
}
~derived(){}
};
我们可以看到drived类虚继承(!!!这个 virtual 不能不能不能去掉)自base类,在模板展开的时候derived类被声明为base类的友类,因此可以访问base中的private的部分。
所以可以调用base中被定义为private的构造和析构,定义derived类型的对象是没有任何问题的。
----
class dderived : public derived{}
dderived 是不能被实例化的。why??? <此处应该由 深入探究c++对象模型 这本书>的。
c++对象模型中,构造顺序是,虚拟基类---基类---虚拟指针---初始化列表中的---构造函数 内部的语句
在我们的例子中,就是虚拟基类(base)---基类(derived)---虚拟指针---初始化列表中的---构造函数(dderived(){}),
所以我们就可以知道先会dderived调用虚拟基类base的构造函数,但是对于dderived来说,base的构造函数是不能访问的,因为base的构造函数被定义为private,
并且ddrived不是base的友员类,所以在用dderive构造对象的时候,链接错误,也就是说明drived是不能够被继承的。
下面显示的链接错误《这里应该有 深入理解c++对象模型》
||=== Build: Debug in rpc (compiler: GNU GCC Compiler) ===| /home/lizhen/codeblocks/rpc/main.cpp||In constructor ‘dderived::dderived()’:| /home/lizhen/codeblocks/rpc/main.cpp|13|error: ‘base<T>::base() [with T = derived]’ is private| /home/lizhen/codeblocks/rpc/main.cpp|28|error: within this context| /home/lizhen/codeblocks/rpc/main.cpp|14|error: ‘base<T>::~base() [with T = derived]’ is private| /home/lizhen/codeblocks/rpc/main.cpp|28|error: within this context| /home/lizhen/codeblocks/rpc/main.cpp||In destructor ‘dderived::~dderived()’:| /home/lizhen/codeblocks/rpc/main.cpp|14|error: ‘base<T>::~base() [with T = derived]’ is private| /home/lizhen/codeblocks/rpc/main.cpp|29|error: within this context| ||=== Build failed: 6 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
============================
但是如果derived不是virtual inherit自base类的话,就不会发生链接错误。
以上是关于如何利用c++编写不能被继承但可以在类外定义对象的类的主要内容,如果未能解决你的问题,请参考以下文章