码迷,mamicode.com
首页 > 编程语言 > 详细

如何利用c++编写不能被继承、但可以在类外定义对象的类

时间:2016-05-27 16:29:23      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:

技术分享
 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++编写不能被继承、但可以在类外定义对象的类

标签:

原文地址:http://www.cnblogs.com/li-daphne/p/5505639.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!