If I have two abstract classes defining a pure virtual function with the same name, but different, non-covariant return types, how can I derive from these and define an implementation for both their functions?
#include <iostream>
class ITestA {
public:
virtual ~ITestA() {};
virtual float test() =0;
};
class ITestB {
public:
virtual ~ITestB() {};
virtual bool test() =0;
};
class C : public ITestA, public ITestB {
public:
/* Somehow implement ITestA::test and ITestB::test */
};
int main() {
ITestA *a = new C();
std::cout << a->test() << std::endl; // should print a float, like "3.14"
ITestB *b = dynamic_cast<ITestB *>(a);
if (b) {
std::cout << b->test() << std::endl; // should print "1" or "0"
}
delete(a);
return 0;
}
As long as I don't call C::test() directly there's nothing ambiguous, so I think that it should work somehow and I guess I just didn't find the right notation yet. Or is this impossible, if so: Why?
Okay, it is possible, and the way isn't too ugly. I have to add an additional level of inheritance:
ITestA ITestB <-- These are the interfaces C has to fulfill, both with test()
| |
ITestA_X ITestB_X <-- These classes implement the interface by calling a
| | function with a different name, like ITestA_test
\__________/ which is in turn pure virtual again.
|
C <-- C implements the new interfaces
Now C has no function test()
, but when casting a C*
to an ITestA*
, the implementation of test()
in ITestA_test
will be used. When casting it to an ITestB*
, even by a dynamic_cast from the ITestA*
, the implementation of ITestB_test
will be used.
The following program prints:
3.14
0
#include <iostream>
class ITestA {
public:
virtual ~ITestA() {};
virtual float test() =0;
};
class ITestB {
public:
virtual ~ITestB() {};
virtual bool test() =0;
};
class ITestA_X : public ITestA {
protected:
virtual float ITestA_test() =0;
virtual float test() {
return ITestA_test();
}
};
class ITestB_X : public ITestB {
protected:
virtual bool ITestB_test() =0;
virtual bool test() {
return ITestB_test();
}
};
class C : public ITestA_X, public ITestB_X {
private:
virtual float ITestA_test() {
return 3.14;
}
virtual bool ITestB_test() {
return false;
}
};
int main() {
ITestA *a = new C();
std::cout << a->test() << std::endl;
ITestB *b = dynamic_cast<ITestB *>(a);
if (b) {
std::cout << b->test() << std::endl;
}
delete(a);
return 0;
}
Does this have any drawbacks you could think of?