Как получить доступ к данным std :: vector из шаблонного класса в C ++ - PullRequest
0 голосов
/ 13 июня 2018

Я пытаюсь реализовать шаблонный класс, который имеет контейнер вектора из стандартной библиотеки в качестве члена.Цель этого класса - создать класс линейной алгебры для моего личного использования.

Предполагается, что класс имеет конструктор, который инициализирует вектор, заполненный только нулями, и две перегрузки оператора [] для доступаданные.

Код выглядит следующим образом:

#include <vector>
#include <iostream>

template<class T>class LinAlg
{
private:
    std::vector<T> mVector;
    int mSize;
public:
    LinAlg(int size);
    T & operator[](int i); 
    T const & operator[] (int i)const;
};

template<class T> LinAlg<T>::LinAlg(int size)
{
    mSize = size;
    std::vector<T> mVector;
    for (int i=0; i<mSize; i++)
    {
        mVector.push_back(0);
    }
}

template<class T> T &  LinAlg<T>::operator[](int i)
{
    return mVector[i];
}

template<class T> T const& LinAlg<T>::operator[](int i)const
{
    return mVector[i];
}

int main()
{
  LinAlg<double> vec(2);
  vec[0] = 1.0; 
  vec[1] = 1.0; 
  for(int i=0; i<2; i++)
  {
      std::cout << vec[i] << '\n'; 
  }
    return 0;
}

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

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

В

template<class T> LinAlg<T>::LinAlg(int size)
{
    mSize = size;
    std::vector<T> mVector; // <- oops
    for (int i=0; i<mSize; i++)
    {
        mVector.push_back(0);
    }
}

std::vector<T> mVector; определяет новую переменную mVector , которая затеняет переменную-член mVector.Локальный mVector эффективно заменяет элемент mVector и инициализируется, загружается 0 и затем отбрасывается, когда заканчивается конструктор.Элемент mVector оставлен по умолчанию инициализирован нулевым размером, что вызывает проблемы позже, когда вы пытаетесь получить доступ к значениям, которые, по вашему мнению, вы сохранили.

Вместо этого вы можете

template<class T> LinAlg<T>::LinAlg(int size)
{
    mSize = size;
    // std::vector<T> mVector;  <- remove this
    for (int i=0; i<mSize; i++)
    {
        mVector.push_back(0);
    }
}

, но std::vector имеет конструктор, который выполняет эту работу за вас, по умолчанию инициализируя элементы size, которыми вы можете воспользоваться в Списке инициализирующих элементов

template<class T> LinAlg<T>::LinAlg(int size):
    mVector(size), mSize(size)
{
}

Кроме того, поскольку std::vector знает его длину, вы можете удалить элемент mSize и заменить его на mVector.size()

0 голосов
/ 13 июня 2018

В своем конструкторе вы объявляете локальную переменную mVector, которая скрывает члена класса с тем же именем.Таким образом, вы заполняете локальную переменную, а не члена класса.Вам нужно удалить локальную переменную:

template<class T> LinAlg<T>::LinAlg(int size)
{
    mSize = size;
    for (int i=0; i<mSize; i++)
    {
        mVector.push_back(0);
    }
}

Теперь, как говорится, вам вообще не нужен цикл, так как std::vector имеет метод resize(), который может заполнить вектор значениями:

template<class T> LinAlg<T>::LinAlg(int size)
{
    mSize = size;
    mVector.resize(size); // <-- will set new elements to 0 by default
}

Альтернативно, вместо этого вы можете использовать собственный конструктор вектора, который делает то же самое:

template<class T> LinAlg<T>::LinAlg(int size)
    : mVector(size) // <-- will set elements to 0 by default
{
    mSize = size;
}

В любом случае, член mSize является избыточным, так как std::vector имеет собственный size() метод, который вы можете использовать при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...