问题
Is it possible to inherit identically named operator which only differ in return type, from two different abstract classes. If so, them:
what is the syntax for implementing operators
what is the syntax for using/resolving operators
what is the overhead in general case, same as for any other virtual function?
if you can provide me with a reference or sample code that would be helpful
thanks
12struct abstract_matrix { 13 virtual double& operator()(int i, int j); 14}; 15 16 struct abstract_block_matrix { 17 virtual double* operator()(int i, int j); 18 }; 19 20struct block_matrix : abstract_matrix, abstract_block_matrix { 21 22};
block matrix needs to provide implementations for both operators, so that it is either a matrix or a block matrix, depending on the context. I do not know how to provide implementation specific to block_matrix class. right now, it is done by passing object wrapped type as the last argument, but that does not seem very clean. I would like to retain pure matrix notation.
回答1:
The return type of a function is not part of it's signature, so you can't have two operator+(i,j)'s in block_matrix - that would be an ambiguous call. So multiple inheritance is sort of a red herring here on this point. You just can't do that.
What are you really trying to do, and why?
In any event, for your other question: virtual operators are exactly like virtual functions in terms of performance and the way they operate. There are just slight semantic differences in how you use them - but under the hood they're just functions like any other.
回答2:
You can't overload on the return type. When a function or an operator is invoked the compiler has to know which one to call. It will not infer that based on what the function(operator) call assigned to.
Looks like your are looking to implement some matrix math. Perhaps if you download DirectX SDK or OpenGL and have a look how they do it, you might get some ideas on how to do it properly.
回答3:
I got it work, but it's wonky. I do love templates.
template<class T>
class Base1
{
};
template<class T>
class Base2
{
};
class Derived;
template<>
class Base1<Derived>
{
public:
double foo(){return 0.1;}
};
template<>
class Base2<Derived>
{
public:
int foo(){return 1;}
};
class Derived
: public Base1<Derived>
, public Base2<Derived>
{
public:
using Base1<Derived>::foo;
};
int main()
{
double sum = 0;
Derived d;
sum += d.foo(); //+ .1
Base1<Derived> * pI = &d;
sum += pI->foo(); //+ .1
Base2<Derived> * pF = &d;
sum += pF->foo(); //+ 1
return (sum*10);
}
I couldn't get it to work without templates, although it seems like it should be able to. I'm not sure if you can get away with just doing templated member functions in the same manner, but my gut says "no".
In terms of code organization, I would then define the Base# stuff right after the definition or declaration of Derived, since that's really what it's for. Keep in mind you can then use typename Base1<Derived> something
to make things prettier.
Edit: Oh, right! It doesn't allow you to do the "using" trick or have different return types, but it's otherwise simpler:
class Derived
: public Base1
, public Base2
{
double Base1::foo(){...}
double Base2::foo(){...}
}
There may be a terrible, horrible, awesome way to combine these two approaches, but I don't think it'll actually help out when using the code. I may get back to you on that.
来源:https://stackoverflow.com/questions/1989969/c-multiple-inheritance-off-identically-named-operator