I want to create an abstract class template, forcing all instances to implement a doStuff
function using a pure virtual function.
I have the following template:
template<class T>
class X
{
public:
X() {};
virtual ~X() {};
virtual X<T>& doStuff(X<T>& x) = 0;
};
And an instance with T= int:
class Y : public X<int>
{
public:
Y();
virtual ~Y();
Y& doStuff(Y& x) {
Y res;
Y& res2 = res;
return res2;
}
};
I get the error message:
In member function ‘Y& Y::doStuff(Y&)’: cannot declare variable ‘res’ to be of abstract type ‘Y’ because the following virtual functions are pure within ‘Y’: X<T>& X<T>::doStuff(X<T>&) [with T = int]
If I change the type of the argument to doStuff
in Y
, everything is fine:
class Y : public X<int>
{
public:
Y();
virtual ~Y();
Y& doStuff(X<int>& x) {
Y res;
Y& res2 = res;
return res2;
}
};
Why can the parameter not be a reference to a Y
object when Y
implements X?
The return value of Y&
does not create a similar error message.
Maybe I am using the wrong approach to achieve what I want - feel free to let me know.
Why can the parameter not be a reference to a Y object when Y implements X?
Because you have to give the exact signature as it was declared in the pure virtual function of the base.
That's why
class Y : public X<int> {
// ...
X<int>& doStuff(X<int>& x) override;
};
works.
See the working Live Demo.
Not to mention that returning a reference to a local variable is undefined behavior.