views:

136

answers:

4
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?

+4  A: 

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*.

James McNellis
Ah, but thats not the case. Then is there a work around where I can declare the overloaded [] to be private in class A, and then lets say class C,D, and E need it, can I inherit it in a non polymorphic fashion?
yShalabi
@yShalabi: I don't understand what you are asking. Would you clarify? (It's probably best if you edit the question and give another example).
James McNellis
@yShalabi: If you don't want it to be polymorphic, then why declare it `virtual` in the base class?
Oli Charlesworth
@Oil Charlesworth I do want it polymorphic, it is just one class needs this operator in another functionality.
yShalabi
@James McNellis I made the edits.
yShalabi
+1  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.

Chris Dodd
C and D need the same signature, B needs a different one.
yShalabi
A: 

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 chars or Sequences, right?

Sanjay Manohar
+3  A: 

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.

Josh Townzen
Well, you never know; Stroustrup may have put that rule in after a long night of drinking only to find afterwards that it was a really good idea ;-)
James McNellis
Thank you man! Appreciate that. Very thorough answer -- thanks!
yShalabi