如何利用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 }
View Code

只要把类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++编写不能被继承但可以在类外定义对象的类的主要内容,如果未能解决你的问题,请参考以下文章

c++

c++知识点总结--友元&运算符重载

Java内部类

C++ 类 - 使用公共变量并在类外定义成员函数

C++中static函数类外定义的时候为啥不写static?

记PHP面向对象编程