#include <iostream>
#include<string>
#include<map>
#include<vector>
#include"thread_pool.h" using namespace std;
template<class T>
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(){}
}; class dderived : public derived{
public:
dderived(){}
~dderived(){}
}; int main()
{
cout << "Hello world!" << endl;
derived d;
d.show();
return ;
}

只要把类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||error: ‘base<T>::base() [with T = derived]’ is private|
/home/lizhen/codeblocks/rpc/main.cpp||error: within this context|
/home/lizhen/codeblocks/rpc/main.cpp||error: ‘base<T>::~base() [with T = derived]’ is private|
/home/lizhen/codeblocks/rpc/main.cpp||error: within this context|
/home/lizhen/codeblocks/rpc/main.cpp||In destructor ‘dderived::~dderived()’:|
/home/lizhen/codeblocks/rpc/main.cpp||error: ‘base<T>::~base() [with T = derived]’ is private|
/home/lizhen/codeblocks/rpc/main.cpp||error: within this context|
||=== Build failed: error(s), warning(s) ( minute(s), second(s)) ===|

============================

但是如果derived不是virtual inherit自base类的话,就不会发生链接错误。

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

  1. [翻译] 编写高性能 .NET 代码--第五章 通用编码与对象设计 -- 类 vs 结构体

    本章介绍了本书其它部分未涉及到的一些编码和设计原则.包含了一些.NET的应用场景,有些不会造成太大危害,有些则会造成明显的问题.剩下的则根据你的使用方法会产生不同的效果.如果要对本章节出现的原则做一个 ...

  2. 如何利用mixin编写media query的代码

    mixins允许文档作者定义的属性对时可以在其他规则集中重用的模式. Media Queries直译就是“媒体查询”.media就是来指定特定的媒体类型,如屏幕(screen),或者“TV”等,其中“ ...

  3. 用c++编写一个不能被继承的类(但是可以在类外部定义该类的对象)

    据我们知道,我们只要把类的构造函数和析构函数定义为private类型,那么就不能够在外部建立给类的对象,也就不能以给类为基类进行继承,因为如果继承,建立对象的时候将要调用基类的构造函数,但是因为为pr ...

  4. LoadRunner利用ODBC编写MySql脚本

    最近做了几周的LoadRunner测试,有一些心得,记录下来,以便以后查找. LoadRunner测试数据库是模拟客户端去连接数据库服务器,因此,需要协议(或者说驱动的支持).LoadRunner本身 ...

  5. 利用反射编写私有 Private 方法的单元测试

    利用反射编写私有 Private 方法的单元测试 最近在添加一个新feature时,鉴于要给自己的代码一是增加代码的强壮性,二是增加代码测试的覆盖率.但是遇到了有些方法是 Private 的,但是在调 ...

  6. 利用java编写的盲注脚本

    之前在网上见到一个盲注的题目,正好闲来无事,便用java写了个盲注脚本,并记录下过程中的坑 题目源码: <?php header("Content-Type: text/html;ch ...

  7. 品味性能之道<九>:利用Loadrunner编写socket性能测试脚本简述

            一.概述         Loadrunner拥有极为丰富的工具箱,供予我们制造出各种奇妙魔法的能力.其中就有此次要讨论的socket套接字操作.     二.socket概述     ...

  8. Python 利用Python编写简单网络爬虫实例3

    利用Python编写简单网络爬虫实例3 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站“http://bbs.51testing. ...

  9. Python 利用Python编写简单网络爬虫实例2

    利用Python编写简单网络爬虫实例2 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站“http://www.51testing. ...

随机推荐

  1. Command Line Client(建库,建表)

    Enter password: ******Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection ...

  2. selenium显示等待解决浏览器未加载完成查找控件的问题

    问题描述:wap版支付成功后,跳转到支付成功页,查找的元素已出现,如图的:元素1,元素2,但是提示查找的元素超时,失败,并且每到这个页面都会报页面超时,不能查找到页面元素 原始代码: try{ op. ...

  3. CSS布局--垂直水平居中

    ···设置两个盒子 <div class="parent"> <div class="child"> </div></ ...

  4. TensorFlow 内置重要函数解析

    概要 本部分介绍一些在 TensorFlow 中内置的重要函数,了解这些函数有时候更加方便我们进行数据的处理或者构建神经网络. 这些函数如下:       tf.one_hot()     tf.ra ...

  5. Virtuabox 虚拟机克隆方法

    起初我觉得直接复制一个.vdi 虚拟硬盘再挂上去就可以了,没想到 Virtualbox居然提示UUID重复,看起来就是有点像com生成的那种ID, 查了一下,才知道原来不能这么用 可以通过Vritua ...

  6. Luogu [P2708] 硬币翻转

    硬币翻转 题目详见:硬币翻转 这道题是一道简单的模拟(其实洛谷标签上说这道题是搜索???),我们只需要每一次从前往后找相同的硬币,直到找到不同的硬币n,然后将找到的前n-1个相同的硬币翻过来,每翻一次 ...

  7. CXF学习记录

    1 apache CXF入门 1.1 下载 官网:cxf.apache.org 下载CXF的开发包: Apache CXF = Celtix + Xfire 支持多种协议: SOAP1.1,1.2 X ...

  8. cf492E. Vanya and Field(扩展欧几里得)

    题意 $n \times n$的网格,有$m$个苹果树,选择一个点出发,每次增加一个偏移量$(dx, dy)$,最大化经过的苹果树的数量 Sol 上面那个互素一开始没看见,然后就GG了 很显然,若$n ...

  9. python实现批量修改文件名

    import os def dele(): # 设置一个计数器 n=0 st = input('请输入你要删除的字符:') for i in f: b = f[n] if st in b: oldna ...

  10. JZOJ 5184. 【NOIP2017提高组模拟6.29】Gift

    5184. [NOIP2017提高组模拟6.29]Gift (Standard IO) Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed ...