#include <iostream>
template <typename oprand>
class AbstractOperation
{
protected:
oprand mLhs;
oprand mRhs;
public:
virtual int operation() = 0;
AbstractOperation(oprand x, oprand y) : mLhs(x), mRhs(y) {}
oprand getLhs() const { return mLhs; }
oprand getRhs() const { return mRhs; }
};
template <typename oprand>
class Addition : public AbstractOperation<oprand>
{
public:
Addition(oprand x, oprand y) : AbstractOperation<oprand>(x, y) {}
int operation();
};
template <typename oprand>
int Addition<oprand>::operation()
{
return mLhs + mRhs; // fails to compile
// return this->mLhs +this->mRhs; // compile successfully
// return AbstractOperation<oprand>::mLhs + AbstractOperation<oprand>::mRhs; //compile successfully
}
class A
{
protected:
int m;
public:
A(int val) : m(val) {}
virtual int fun() = 0;
};
class B : public A
{
public:
B(int val) : A(val) {}
int fun() { return m; }
};
int main()
{
A *a = new B(5);
std::cout << a->fun() << "\n";
AbstractOperation<int> *p = new Addition<int>(4, 5);
std::cout << p->operation() << "\n";
delete a;
delete p;
}