【问题标题】:Private inheritance causing problem in c++ [duplicate]私有继承导致c ++中的问题[重复]
【发布时间】:2020-03-13 16:59:25
【问题描述】:

为什么下面的代码会遇到‘A’ is an inaccessible base of ‘B’的错误?这是我的想法:

  • 每当我们调用函数 foo() 时,它都会执行new B(5),它会首先调用其基础结构 A 的构造函数。

  • struct A 的构造函数是一个公共方法,因此它应该可以被其派生的 struct B 访问(如果我没记错的话,它是受保护的)。

  • 然后会调用结构B的构造函数来创建一个有五个0的向量。

  • 然后删除对象a会调用析构函数B,然后是析构函数A。

我的逻辑有什么问题吗?您的回答将不胜感激

#include <iostream>
#include <vector>

using namespace std;

struct A 
{ 
    A() { cout << "Constructor A called"<< endl;} 
    virtual ~A() { cout << "Denstructor A called"<< endl;}
};

struct B : private A
{
    vector<double> v;
    B(int n) : v(n) { cout << "Constructor B called"<< endl;}
    ~ B() { cout << "Denstructor B called"<< endl;}
};

int main()
{
    const A *a = new B(5);
    delete a;

    return 0;
}

【问题讨论】:

  • 因为你做了继承private,外界没有人知道这个继承存在。所以从外面看,AB 是不相关的类型。

标签: c++


【解决方案1】:

你的逻辑没有错,只是少了一点:

private 继承基本上意味着只有继承类(在这种情况下为 B知道它从基类 A 继承。 这反过来意味着只有B 可以使用此继承附带的所有特权。其中一项特权是能够将B* 转换为A*。函数foo() 不知道B 的继承,因此它无法执行该转换。

【讨论】:

  • 值得注意的是,protected 继承也会出现同样的问题。简而言之,不仅仅是因为它是private;更一般地说,这是因为它公开也不加好友(是的,你可以Bfriend void foo();,从而授予foo访问B的权限对A 的受保护或私有继承,从而使这两种情况工作)。
  • @WhozCraig 对。另外值得注意的是,访问限定符对成员和继承的工作方式没有区别:当您声明成员publicprotectedprivate 时,您指定谁可以访问该成员,谁不能访问该成员。当您声明继承publicprotectedprivate 时,您指定谁可以“访问”该继承,谁不能,即谁可以使用它(例如执行强制转换或访问基类成员) .在这两种情况下,授予您访问权限或不授予您访问权限的规则完全相同。
【解决方案2】:

TL;DR

您从 A 派生 B 作为“私有”。您必须将其更改为

struct B : public A{
    vector<double> v;
    B(int n): v(n) {std::cout << "B Constructor" << std::endl};
    ~B() {std::cout << "B Destruktor" << std:.endl;};
};

扩展说明

通过使用私有继承,您可以定义B has a A 而不是B is a A。使用has-a 依赖项,您不能在两个类之间进行向上和向下转换(Apple 不能成为蠕虫,反之亦然。即使苹果有蠕虫)。

如果你想利用另一个类实现的特性,你主要使用私有继承,而不暴露所使用类的公共接口。例如您可以在自己的类中使用解析器的功能,而无需自己成为解析器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 2014-06-21
    • 2011-09-17
    • 1970-01-01
    • 2021-07-16
    • 2011-05-30
    • 2017-12-01
    • 2013-07-27
    相关资源
    最近更新 更多