Как перегрузить оператор "[]" для вектора, содержащего мои собственные объекты класса - PullRequest
0 голосов
/ 18 апреля 2019

Итак, я получил класс WayPoint (внутри пространства имен HHN). И я получил класс WayPointContainer. Контейнер получил приватную векторную переменную для хранения объектов типа "HHN :: WayPoint"

Что я хочу сделать сейчас, так это перегрузить оператор [], чтобы я мог легкий доступ к объектам внутри вектора, например:

WayPoint p1("name",1.5,2.0);
WayPointContainer c1; 
c1[0] = p1          // This would add the WayPoint p1 to the vector of the container on index 0
WayPoint p2 = c1[0] // This would get the WayPoint from the vector at index 0 and copy it to p2

...

Я нашел разные реализации, но они были для других типов, кроме вектора, или не использовали сложный тип внутри вектора.

Вот мой WayPointContainer.h

#include <vector>
#include <iostream>
#include "WayPoint.h"

#ifndef SRC_WAYPOINTCONTAINER_H_
#define SRC_WAYPOINTCONTAINER_H_

class WayPointContainer {
    private:
        std::vector<HHN::WayPoint>* pContainer{ nullptr };

    public:
        WayPointContainer();
        WayPointContainer(const WayPointContainer& orig);
        virtual ~WayPointContainer();

        WayPointContainer& operator=(const WayPointContainer& rhs);
        HHN::WayPoint& operator[](int idx) const;

        void Add(const HHN::WayPoint& arg);

        int Size() const;
        void Print() const;
};

#endif /* SRC_WAYPOINTCONTAINER_H_ */

Вот мой WayPointContainer.cpp

#include <vector>
#include "WayPointContainer.h"
#include <iostream>
using namespace std;

//Default Konstruktor
WayPointContainer::WayPointContainer() {
    //Heap bereich ... new ... pContainer
    pContainer = new std::vector<HHN::WayPoint>;
}

//Destruktor
WayPointContainer::~WayPointContainer() {} //TODO

//Copy Konstruktor
WayPointContainer::WayPointContainer(const WayPointContainer& orig) {
    pContainer = orig.pContainer;
}

WayPointContainer& WayPointContainer::operator=(const WayPointContainer& rhs) {
    if(&rhs == this) {
        return *this;
    }
    if ( pContainer != rhs.pContainer) {
        pContainer = rhs.pContainer;
    }
    return *this;
}

HHN::WayPoint& WayPointContainer::operator[](int idx) const {*
    //invalid initialization of reference of type 'HHN::WayPoint&' from expression of type 'std::vector<HHN::WayPoint>'
    return pContainer[idx];
}

void WayPointContainer::Add(const HHN::WayPoint& arg) {
    pContainer->insert(pContainer->begin(), arg);
}

int WayPointContainer::Size() const {
    int i = pContainer->size();
    return i;
}

void WayPointContainer::Print() const {
    for (auto waypoint = pContainer->begin(); waypoint != pContainer->end(); ++waypoint) {
        cout << waypoint->Name();
    }
}

Метод, с которым я борюсь:

HHN::WayPoint& WayPointContainer::operator[](int idx) const {*
    //invalid initialization of reference of type 'HHN::WayPoint&' from expression of type 'std::vector<HHN::WayPoint>'
    return pContainer[idx];
}

Код, который я там реализовал, получил ошибку неверной инициализации, описанную выше.

Так что я ожидаю использовать [] -оператор, как описано выше, но сейчас он не реализован или не реализован с ошибкой.

(мне также не хватает деструктора для вектора "pContainer" внутри деструктора WayPointContainer. Так что, если это что-то, что вы знаете, можете добавить его, но это не мой вопрос, а просто бонус.)

Если вы хотите, я также могу предоставить код, который я получил для класса WayPoint и моего main.cpp, который я использую для его тестирования.

1 Ответ

1 голос
/ 18 апреля 2019

Сообщение об ошибке совершенно ясно о непосредственной проблеме в реализации вашего оператора

invalid initialization of reference of type 'HHN::WayPoint&' from expression of type 'std::vector<HHN::WayPoint>'

pContainer[idx] разыменовывает pContainer со смещением idx, таким образом, результатимеет тип std::vector<HHN::WayPoint>.

Существует два способа решения проблемы:

  1. Вы можете разыменовать указатель и применить к нему idx:

    return (*pContainer)[idx];
    
  2. Вы вообще не используете указатель для удержания члена std::vector<HHN::WayPoint> (рекомендуемое решение):

    class WayPointContainer {
         private:
             std::vector<HHN::WayPoint> container;
         // ...
    };
    

    В этом случае вы не будетенеобходимо иметь дело с распределением памяти для указателя и просто записать перегрузку вашего оператора как

    HHN::WayPoint& WayPointContainer::operator[](int idx) const {
         return container[idx];
    }
    
...