Skip to content

Instantly share code, notes, and snippets.

@sherm1
Last active May 12, 2016 05:50
Show Gist options
  • Save sherm1/c00eb8ac71ec7678ee2fdcfe87812c04 to your computer and use it in GitHub Desktop.
Save sherm1/c00eb8ac71ec7678ee2fdcfe87812c04 to your computer and use it in GitHub Desktop.
Multi-inheritance & NVI
// Demonstrates mild multiple inheritance and Non-Virtual Interface.
// The base classes cannot be pure interfaces; they have private data
// and code, but unambiguous semantics. The only slightly-odd behavior
// is that a static_cast of a derived class to one of the bases shifts
// its memory address (see below).
#include <iostream>
using std::cout; using std::endl;
// A base class.
class Continuous {
public:
double GetDerivative() const {
++deriv_count_;
return GetDerivativeImpl();
}
int get_num_derivs() const { return deriv_count_; }
virtual ~Continuous() = default;
protected:
Continuous() = default;
virtual double GetDerivativeImpl() const = 0;
private:
mutable int deriv_count_{}; // could be static to get total count
};
// Another base class.
class Discrete {
public:
double GetUpdate() const {
++update_count_;
return GetUpdateImpl();
}
int get_num_updates() const { return update_count_; }
virtual ~Discrete() = default;
protected:
Discrete() = default;
virtual double GetUpdateImpl() const = 0;
private:
mutable int update_count_{};
};
// Derived class implements protected pure virtuals.
class MySystem : public Continuous, public Discrete {
private:
double GetDerivativeImpl() const override { return 1.; }
double GetUpdateImpl() const override { return 2.; }
};
// Another derived class.
class YourSystem : public Continuous, public Discrete {
private:
double GetDerivativeImpl() const override { return 10.; }
double GetUpdateImpl() const override { return 20.; }
};
int main() {
MySystem sys;
cout << "Deriv=" << sys.GetDerivative() << endl;
cout << "Update=" << sys.GetUpdate() << endl;
cout << "Update=" << sys.GetUpdate() << endl;
cout << "nderivs=" << sys.get_num_derivs() << endl;
cout << "nupdates=" << sys.get_num_updates() << endl;
cout << "&sys=" << &sys << endl;
cout << "&Cont(sys)=" << &static_cast<Continuous&>(sys) << endl;
cout << "&Disc(sys)=" << &static_cast<Discrete&>(sys) << endl;
return 0;
}
@sherm1
Copy link
Author

sherm1 commented May 12, 2016

Output:

Deriv=1
Update=2
Update=2
nderivs=1
nupdates=2
&sys=0x7ffc8a65e3a0
&Cont(sys)=0x7ffc8a65e3a0
&Disc(sys)=0x7ffc8a65e3b0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment