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?
Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading.
In C you can't have two functions with the same name, at all. In C++, it's entirely possible as long as the function function signature is different, ie two functions having the same name but different set of parameters.
Rules in function overloading The same function name is used for more than one function definition. The functions must differ either by the arity or types of their parameters.
Yes, its possible to use the same parameter name several times, given parameters have local scope. But i wouldn't define it as fine, function names, variable names, parameters and so forth should have logic names, this makes the code so much more understandable and easier to read.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With