从另一个子集内的子集内访问超集变量

时间:2017-09-27 01:20:22

标签: c++ class subset superclass superset

在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类中的President类内的方法访问Subset

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

3 个答案:

答案 0 :(得分:2)

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

班级D应该从班级B继承,如果他们之间存在is a的关系,即D is a B

在您的示例中,从CIAPresident继承是没有意义的,因为该实体同时是CIA 总裁。我认为这违反宪法(或者至少是违法的)。

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

答案 1 :(得分: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;
}

答案 2 :(得分:0)

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

可以将此动态广播到Subset *(并且也可以使用c风格的类型转换(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风格的演员阵容,这是不必要的。

虽然第二个想法是,添加虚拟函数而不是更改doAliensExist()也可以:

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