代码之家  ›  专栏  ›  技术社区  ›  Priyanka Mishra

不为私有继承类创建动态对象

  •  0
  • Priyanka Mishra  · 技术社区  · 15 年前

    以下代码不允许我创建对象的原因是什么?

    class base
    {
        public:
            void foo()
            { cout << "base::foo()"; }
    };
    
    class derived : private base
    {
        public:
            void foo()
            { cout << "deived::foo()"; }
    };
    
    void main()
    {
        base *d = new derived();
        d->foo();
    }
    

    它给了我错误:

    “type cast”:转换自 “derived*”到“base*”存在,但为 难以接近的

    事先谢谢:)

    6 回复  |  直到 14 年前
        1
  •  3
  •   Gorpik    15 年前

    问题是您使用的是私有继承;这意味着继承只能在类内部看到(在本例中, derived )你不能点A base* 衍生的 类外部的实例(在本例中,在 main() )因为无法访问继承(因此也无法访问转换)。

    这与尝试从类外部访问私有成员完全相同。

    事实上,“私有继承”这个名字很容易引起误解,因为它不实现真正的继承。在您的示例中,a 衍生的 实例不是 base ;它只是根据 基础 这就是“私有继承”的含义。如果您想使用私有继承,那么应该考虑使用简单聚合的可能性(即:私有指针指向 基础 里面 衍生的 相反。在大多数情况下(大多数情况下,并非总是如此),私有继承没有优势,并且存在一些微妙的问题。

        2
  •  2
  •   anon    15 年前

    因为使用了私有继承,派生对象不是基对象。所以当你说:

     base *d = new derived();
    

    指向派生的指针无法转换为指向基的指针-两者之间没有实际关系。但是,您可以创建派生对象:

    derived d;
    derived * dp = new derived();
    
        3
  •  0
  •   aJ.    15 年前

    私有继承导致基类详细信息在派生类之外不可见。因此,错误C2243:access protection(protected或private)阻止了从指向派生类的指针到指向基类的指针的转换。

    你应该使用公共继承。

        4
  •  0
  •   Exa    15 年前

    有两种方法可以使其工作:

    class base
    {
        public:
            void foo()
            { std::cout << "base::foo()"; }
    };
    
    class derived : public base // <-- make it public
    {
        public:
            void foo()
            { std::cout << "derived::foo()"; }
    };
    
    void main()
    {
        base *d = new derived();
        d->foo();
    }
    

    或:

    class base
    {
        public:
            void foo()
            { std::cout << "base::foo()"; }
    };
    
    class derived : private base
    {
        public:
            void foo()
            { std::cout << "derived::foo()"; }
    };
    
    void main()
    {
        derived *d = new derived(); // create pointer on derived, not base
        d->foo();
    }
    

    希望能有所帮助, 埃克萨

        5
  •  0
  •   SVGreg    14 年前

    参见C++标准中的CH.112.3(草案)。必须使用显式强制转换,因为隐式强制转换(base*d=new derived();)中使用的复制构造函数不可访问。

        6
  •  -1
  •   DaClown    15 年前

    我猜:编译器创建的基类的默认构造函数/复制构造函数是私有的,因为对派生类的私有继承,不能由类型转换使用