0

在 C++ 类中,如何从另一个子集中访问超集的变量?这只能直观地显示为示例,以供您理解。

中央情报局高于总统,有权对总统保密信息。

class CIA {
public:
    bool aliensExist = true; // 100%
};

class President {
public:
    bool doAliensExist() {
        return aliensExist; // Not sure, no access to CIA's aliensExist variable
    }
};

class Subset : public President, public CIA {

};

int main() {
    Subset subset;
    cout << "Aliens exist = " << subset.doAliensExist() << endl;
}

如何从类内aliensExist使用类内的方法访问?PresidentSubset

我知道上面的例子是不合逻辑的,当然如果没有它的直接子集President就无法访问CIA,但我想知道这样的事情有什么好的方法?

4

3 回答 3

2

您(过度)使用继承错误。当然,你很难找到解决方案,因为模型根本上是错误的。您似乎认为类层次结构在某种程度上类似于数学集......

一个类D应该从一个类继承,如果它们之间B存在关系is a,即D is a B.

在您的示例中,从两者继承是没有意义的CIAPresident因为该实体将同时是中央情报局总统。我认为这违反了宪法(或至少是非法的)。

所以你需要改变你的模型。OOP 和继承不是圣杯,不是万能的解决方案。

于 2017-09-27T10:17:29.880 回答
1
#include <iostream>
#include <stdexcept>

using namespace std;

class CIA {
public:
    bool aliensExist = true;
};

class President {
public:
    bool doAliensExist() {
        return _doAliensExist();
    }

private:
    virtual bool _doAliensExist() {
        throw runtime_error("cannot access");
    }
};

class Subset : public President, public CIA {
private:
    virtual bool _doAliensExist() {
        return aliensExist;
    }
};

int main() {
    cout << "Aliens exist = " << Subset().doAliensExist() << endl;
}
于 2017-09-27T01:45:48.343 回答
0

好吧,我不建议在生产代码中使用它,但因为这似乎是一个理论问题......

可以将它 dynamic_cast 为 Subset* (也可以使用 c 风格的类型 cast (Subset*)this,但在不兼容的类的情况下不会抛出):

#include <iostream>
#include <stdexcept>
using namespace std;

class CIA {
public:
    bool aliensExist = true;
};

class President {
public:
    virtual bool doAliensExist();
};

class Subset : public President, public CIA {
};

bool President::doAliensExist() {
    Subset* subset = dynamic_cast<Subset*>(this);
    if(!subset)
    {
      std::runtime_error("cannot access");
    }
    return subset->aliensExist;
}

int main() {
    Subset subset;
    cout << "Aliens exist = " << subset.doAliensExist() << endl;
}

在问题中对总统的修改没有明确的限制,因此可以将 doAliensExist() 设为虚拟以使类具有多态性。使用 c-style cast,就没有必要了。

虽然再想一想,添加一个虚函数而不是更改 doAliensExist() 也可以:

class President {
public:
    bool doAliensExist();
    virtual void dummy() {};
};
于 2017-09-27T05:40:30.470 回答