Can I override an overload of an operator and return a different type?
class A{
public:
virtual char &operator[](int);
protected:
..
};
class B:A{
public:
A* &operator[](int);
protected:
}
Can I change the return type when I overload an overload of an operator?
thanks!
//EDIT Okay, so now that we established that this wont work how can I build a work around?
Lets say I have classes A,B,C, and D.
class A{
public:
private:
char &operator[](int);
protected:
..
};
class开发者_运维百科 B:A{
public:
virtual char &operator[](int);
};
class C: A{
public:
private:
A::&operator[](int);
}
class D: A{
public:
private:
A::&operator[](int);
}
Can I do something like this? If so is this the correct syntax?
Not like this, no.
The return type of an override must be either
- the same type as the return type of the virtual function being overridden, or
- a derived class of the return type of the virtual function being overridden (this is called a "covariant return type").
So, if a virtual A::operator[]
returned an A*
, then a B::operator[]
override could return a B*
.
The reason that a polymorphic function can't return different types in different classes isn't because someone on the C++ committee decided that it was "taboo", but because any code that used that function's return value couldn't compile.
By creating an inheritance heirarchy, you're able to access derived objects through a base pointer or reference:
class A
{
public:
virtual char operator[](int);
};
class B : public A
{
public:
virtual char operator[](int);
};
A *a;
std::cout << "Do you want to make an A or a B?";
char type;
std::cin >> type;
if (type == 'A')
a = new A();
else
a = new B();
char c = (*a)[0];
Note that on the last line, the compiler won't know what type of object a
is pointing to, since that's determined at runtime. This is fine, because no matter what type of object a
is pointing to, operator[]
is still going to return a character. But what if that operator were allowed to return a different type in class B
?
class Sequence
{
...
};
class A
{
public:
virtual char operator[](int);
};
class B : public A
{
public:
virtual Sequence operator[](int);
};
A *a = new B();
char c = (*a)[0];
Obviously, that last line makes no sense when a
is an object of type B
. In that case, you're trying to assign a Sequence
to a character. Likewise, Sequence c = (*a)[0];
wouldn't make sense if a
were an object of type A
.
The proper solution is to make A
a member of classes C
and D
rather than a base class. Since C
and D
need a different signature for a public method, they're clearly not equivalent to an A
in every context, so trying to use inheritance here really makes no sense.
OK looking at your last comment about Sequence (A
), GeneSequence (B
) and GenomeSequence (C
)
you want the operator to sometimes return a char
, and sometimes return a Sequence
well then, as you can see, it is incorrect for the superclass A
to declare the type of &operator []
as char
.
It should use a template as a type parameter, to specify whether it is a collection of char
s or Sequence
s, right?
精彩评论