C++继承:保护变量不可用

4

我在XCode中有以下的C++代码,出现了两个我无法理解的错误:

#include <iostream>


class Buch{
public:
    Buch (long int nummer = 0, char autor[25] = (char*)"", int jahr = 0, bool ausgel = false);

    long int getNr();
    int getJahr();

protected:
    long int __nummer;
    char     __autor[25];
    int      __jahr;
    bool     __ausgel;

    void setAusl(bool x);
    bool getAusl();
};

class FachBuch : Buch {
public:
    void setSWort(int sw);
    int getSWort();

protected:
    char     __fach[15];
    int      __swort;
};

class UBuch : Buch {
public:
    void setAlter(int a);
    int getAlter();

protected:
    int      __kateg;
    char     __land[15];

private:
    int _ab_alter;
};

class Bildband : UBuch {
public:
    Bildband(long int nummer = 0, char autor[25] = (char*)"", int jahr = 0, int kategorie = 0, char land[15] = (char*)"");
};

Buch::Buch (long int nummer, char autor[25], int jahr, bool ausgel) {
    __nummer = nummer;
    //_autor = autor;
    __jahr = jahr;
    __ausgel = ausgel;
}

long int Buch::getNr() {
    return __nummer;
}

int Buch::getJahr() {
    return __jahr;
}

void Buch::setAusl(bool x) {
    __ausgel = x;
}

bool Buch::getAusl() {
    return __ausgel;
}


void FachBuch::setSWort(int x) {
    __swort = x;
}

int FachBuch::getSWort() {
    return __swort;
}


void UBuch::setAlter(int x) {
    _ab_alter = x;
}

int UBuch::getAlter() {
    return _ab_alter;
}

Bildband::Bildband(long int nummer, char autor[25], int jahr, int kategorie, char land[15]) {

    __nummer = nummer; // error message: Cannot cast 'Bildband' to its private base class 'Buch'

    //Buch(nummer, autor, jahr, false); // error message: '__nummer' is a private member of 'Buch'

}

int main () {
    Bildband Masuren(356780, (char*)"Kranz", 2010, 4, (char*)"Polen");
    return 0;
}

我收到了以下错误信息: main.cpp:92:5: 无法将“Bildband”强制转换为其私有基类“Buch” main.cpp:92:5:“__nummer”是“Buch”的私有成员
我的C ++知识非常有限,我在谷歌上也没有找到答案,可能主要是因为我缺乏必要的C ++基础知识。
有人能解释一下这些错误发生的原因,并告诉我需要查找哪些术语来理解问题吗?
提前致谢。

3
不确定你不理解的部分是什么,但你知道你正在使用私有继承吗? - juanchopanza
你需要查找的术语是 protected - Mooing Duck
5
含有相邻下划线的名称是保留标识符 - chris
2
很可能,class FachBuch : Buch 应该改为 class FachBuch : public Buch - cdhowie
另外,struct FachBuch : Buch - juanchopanza
3个回答

9

它们不可用是因为UBuch私有继承Buch。在定义一个类时,默认情况下继承是私有的。

// These two lines mean the same thing:
class UBuch : Buch
class UBuch : private Buch
Buch 的所有成员都是被继承的,但对于 UBuch 可见的成员是作为私有的,只属于 UBuch 继承的。
这意味着外部代码无法访问 UBuch 对象上 Buch 的任何成员,也不能将指向 UBuch 对象的指针或引用转换为指向 Buch 的指针或引用。 这包括派生自 UBuch 的类。
class Bildband : UBuch

尽管Buch在继承链中,但其成员被UBuch私有继承,因此Bildband无法访问从Buch继承的成员。

为了解决这个问题,您应该公开继承Buch(并且您可能希望所有其他类都从它们各自的基类公开继承):

class UBuch : public Buch

此外,请注意,包含两个连续下划线的标识符被环境保留,因此代码中的所有这类标识符(例如__nummer__autor等)都会导致未定义行为

1

如果你没有定义一个存取说明符,编译器会默认为类使用私有继承。只需在 UBuch 类和 Buch 类前添加 "public" 来指定公共继承:

// ...
class UBuch : public Buch {
// ...
class Bildband : public UBuch {

我假设这里是“公共的”,因为我猜想你想让BildBand的用户也能够访问getNr / getJahr等方法。
./问候 弗洛里安

1

编辑:请参见下面的评论

继承类型会影响哪些成员被继承:

公共继承意味着只有公共成员被继承。

保护继承意味着公共成员被继承,受保护的成员也被继承为受保护的成员。

私有继承意味着公共成员被继承,受保护的成员也被继承为私有成员。

在这里,默认情况下您正在进行私有继承。


不,公共继承意味着所有成员都被继承。 - cdhowie
1
私有成员永远不会被继承。 受保护的成员不会被公共继承。 - user3126802
它们是被继承的,但对于派生类来说不可见(否则它们就不存在了)。即使我承认这一点,public 也会导致 protected 成员被继承为 protected,否则进一步派生的类将无法使用祖先的 protected 成员。 - cdhowie
换句话说,一个类总是继承其父类的所有成员,但不会继承对私有成员的访问 - cdhowie
1
你是对的!感谢纠正我!抱歉造成混淆!我会编辑答案。 - user3126802
1
我相信以下链接很好地总结了答案: http://www.programiz.com/cpp-programming/public-protected-private-inheritance - user3126802

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接