0

In C++ classes, how can I access a super-set's variable from within another sub-set? This can only be shown visually as an example for you to understand.

The CIA is above the President and have the right to keep confidential information from the President.

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;
}

How can I access aliensExist using the method inside President class from within the Subset class?

I know the example above is illogical and of course President cannot access CIA without it being a direct subset of it, but I'm wondering what's a good approach for something like this?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Ari Seyhun
  • 11,506
  • 16
  • 62
  • 109
  • 1
    Make `doAliensExist()` an abstract method, and override it in `Subset`. For more information [see your C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Sam Varshavchik Sep 27 '17 at 01:36
  • The base classes have no knowledge of each other. The `Subset` class has, and might be able to coordinate. – Bo Persson Sep 27 '17 at 01:37
  • Unless you are more specific on "something like this" you'll get only comments or down votes. As 2 previous comments say, there might be way to achieve what you want, but you should clearly tell what it is that you want indeed as clearly example isn't representative (you can't access aliensExist from President as you say yourself) – isp-zax Sep 27 '17 at 01:41
  • @SamVarshavchik I'll look into what abstract methods are in C++! BoPersson That's a good idea, I'll look into that too – Ari Seyhun Sep 27 '17 at 01:45

3 Answers3

2

You are (over)using inheritance wrong. Of course you have problem finding a solution, because the model is fundamentally wrong. You seem to be under the impression that class hierarchy is somehow analogue to mathematical sets...

A class D should inherit from a class B iff there is a relation of is a between them, i.e. D is a B.

In your example it doesn't make sense to inherit from both CIA and President because that entity would be CIA and president at the same time. I think that's against the constitution (or at least illegal).

So you need to change your model. OOP and inheritance isn't a holy grail, a fix for everything.

bolov
  • 72,283
  • 15
  • 145
  • 224
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;
}
boriaz50
  • 860
  • 4
  • 17
  • It's a working answer, but I'll wait in case there are other answers. It would be preferable if `Subset` class did not need to coordinate any of it, only the `President` class, but it seems like a solution at least. – Ari Seyhun Sep 27 '17 at 01:50
0

Well, I wouldn't recommend using it in production code, but since this seems to be a theoretical question...

It's possible to dynamic_cast this to Subset* (and it would also be possible to use c-style type cast (Subset*)this, but that would not throw in case of incompatible classes):

#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;
}

there was no clear limitations on modifications to the President in the question, so supposedly it's okay to make doAliensExist() virtual to make class polymorphic. With c-style cast, that wouldn't be necessary.

Although on a second thought, adding a virtual function instead of changing doAliensExist() would do just as well:

class President {
public:
    bool doAliensExist();
    virtual void dummy() {};
};
isp-zax
  • 3,833
  • 13
  • 21