#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. nvm安装nodejs(安装在非系统盘内)

    在使用nodejs时有时需要不同的版本之间进行切换,所以就用到了版本管理工具nvm,在windows系统下用的是nvm-windows,这里选择的是nvm-noinstall.zip免安装版本(需要配 ...

  2. java Vamei快速教程06 组合

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经尝试去定义类.定义类,就是新建了一种类型(type).有了类,我们接着构造 ...

  3. Internationalization(i18n) support in SAP CRM,UI5 and Hybris

    i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是"国际化"的简称.对程序来说,在不修改内部代码的情况下,能根据不同语言及 ...

  4. 【BZOJ1857】传送带(分治经典:三分套三分)

    点此看题面 大致题意: 一个二维平面上有两条传送带\(AB\)和\(CD\),\(AB\)传送带的移动速度为\(P\),\(CD\)传送带的移动速度为\(Q\),步行速度为\(R\),问你从\(A\) ...

  5. geoWithin查询 多边形查询

    $geoWithin查询 形状的表示 .$box:矩形,使用 {$box:[[<x1>,<y1>],[<x2>,<y2>]]}表示 都是坐标,第一个坐标 ...

  6. Count Numbers(矩阵快速幂)

    Count Numbers 时间限制: 8 Sec  内存限制: 128 MB提交: 43  解决: 19[提交] [状态] [讨论版] [命题人:admin] 题目描述 Now Alice want ...

  7. install cmake,install torch7

    cmake http://blog.csdn.net/jesse__zhong/article/details/21290675 torch7 http://wanghaitao8118.blog.1 ...

  8. Oracle 表的连接方式

    1. 连接说明 ① Oracle一次只能连接两个表.不管查询中有多少个表,Oracle 在连接中一次仅能操作两张表. ② 当执行多个表的连接时,优化器从一个表开始,将它与另一个表连接:然后将中间结果与 ...

  9. Java十进制转成二进制 八进制 十六进制

    int a = 357;//十进制转成二进制System.out.println(Integer.toBinaryString(a)); package com.swift; import java. ...

  10. 【Python学习之九】asyncio—异步IO

    asyncio 这是python3.4引入的标准库,直接内置对异步IO的支持.asyncio的编程模型就是一个消息循环.从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程 ...