rize
rize

Reputation: 859

Class storing pointers to vector in C++

I'm implementing a class Aviary, which can store pointers to Bird-objects. Now, I have the following:

class Aviary {

public:
    const Bird &operator[](const size_t index) const {
    return birds[index];
    }

    Bird &operator[](const size_t index) {
    return birds[index];
    }

private:
    std::vector<Bird*> birds;

The Bird-objects are stored as pointers in order to avoid object-slicing. However, there is a problem with the operator[]-implementation (Reference to type 'const Bird' could not bind to an lvalue of 'const value_type' (aka 'Bird *const')).

How do I implement the operator[] properly?

Upvotes: 0

Views: 255

Answers (3)

Gorpik
Gorpik

Reputation: 11028

Two side notes:

  1. The const in a parameter passed by value (const size_t index) is useless and your compiler will ignore it. You can try declaring it with const and removing the const in the implementation: the compiler will correctly consider that your implementation matches the declaration.
  2. The canonical way to implement the non-const version of operator[] is as follows:

As follows

Bird &operator[](size_t index) {
  return const_cast<Bird&>(const_cast<const Aviary*>(this)->operator[](index));
}

I know all those const_cast look ugly, but they are both safe and this is the right way to ensure that both versions of operator[] do the same (you just need to maintain the const version from now on), while also making sure that your are not doing any non-const operation in the const version.

Apart from that, the problem with your code is that you are returning pointers, not (references to) the values pointed by them, as Luchian and ForEveR have already pointed out.

Upvotes: 1

ForEveR
ForEveR

Reputation: 55887

Since you store pointers, you should dereference the pointer for return reference.

const Bird &operator[](const size_t index) const {
return *birds[index];
}

Bird &operator[](const size_t index) {
return *birds[index];
}

Side note: use smart pointers, instead of raw pointers.

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258568

You need to dereference:

return *(birds[index]);

birds[index] is a Bird*, so you can't directly return it as a Bird&.

Upvotes: 0

Related Questions