代码之家  ›  专栏  ›  技术社区  ›  Vijay

无法派生的类

c++
  •  4
  • Vijay  · 技术社区  · 14 年前

    我找到了这个密码 here

    class Usable;
    
    class Usable_lock {
        friend class Usable;
    private:
        Usable_lock() {}
        Usable_lock(const Usable_lock&) {}
    };
    
    class Usable : public virtual Usable_lock {
        // ...
    public:
        Usable();
        Usable(char*);
        // ...
    };
    
    Usable a;
    
    class DD : public Usable { };
    
    DD dd;  // error: DD::DD() cannot access
            // Usable_lock::Usable_lock(): private  member
    

    有人能解释一下这个密码吗?

    编辑 :还有一个问题是什么是虚拟派生,什么时候需要?

    3 回复  |  直到 14 年前
        1
  •  5
  •   Matthieu M.    14 年前

    它是 virtual 推导。

    理念 事实上的 推导是为了解决“可怕的钻石图案”:

    struct Base {};
    
    struct D1: Base {};
    struct D2: Base {};
    
    struct TopDiamond: D1, D2 {};
    

    问题是 TopDiamond 有2个实例 Base 在这里。

    为了解决这个问题,非常独特的“多重继承”,C++使用了 事实上的 关键字和所谓的“虚拟继承”。

    如果我们改变方式 D1 D2 定义如下:

    struct D1: virtual Base {};
    struct D2: virtual Base {};
    

    那么只有一个 基地 在内部 顶级钻石 :实际实例化它的工作留给顶级构造函数(这里 顶级钻石 )

    因此,您所展示的小技巧在此简单说明:

    • 因为 Usable 实际上来自 Usable_lock ,由其派生类来实例化 通用锁 物体的一部分
    • 因为 通用锁 构造函数是 private ,只有它自己和 可用的 (朋友)可以访问构造函数

    很聪明,我从来没想过。我想知道 事实上的 继承在这里(额外的内存/速度开销)?

        2
  •  1
  •   Mihir Mehta    14 年前

    Usable_lock 的构造函数在private下声明 所以在外面是无法接近的

    Usable_lock class 
    

    当你制造对象

     DD dd;
    

    它将调用 Usable Usable_Lock 两者都是(因为 DD 来源于 可用的 可用的 来源于 通用锁 )

    因此它无法访问可用的锁的构造函数。它会给你错误

        3
  •  1
  •   Alex F    14 年前

    这里有两点:

    1)为什么可以创建可用实例,尽管它涉及私有可用锁构造函数?因为可用是可用锁的朋友。

    2)为什么不能创建可用的派生实例?因为它涉及私有可用的锁构造函数。