zoukankan      html  css  js  c++  java
  • 如何利用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类的话,就不会发生链接错误。

  • 相关阅读:
    SoapUI 使用笔记
    git 使用笔记(二)
    git 使用笔记(一)
    jquery 拓展
    hdu 1024 Max Sum Plus Plus (DP)
    hdu 2602 Bone Collector (01背包)
    hdu 1688 Sightseeing (最短路径)
    hdu 3191 How Many Paths Are There (次短路径数)
    hdu 2722 Here We Go(relians) Again (最短路径)
    hdu 1596 find the safest road (最短路径)
  • 原文地址:https://www.cnblogs.com/li-daphne/p/5505639.html
Copyright © 2011-2022 走看看