如何从C ++中的模板化类访问std :: vector数据

时间:2022-01-28 16:39:48

I am trying to implement a templated class that has a vector container from the standard library as a member. The purpose of the class is to create a linear algebra class for my personal use.

我试图实现一个模板化的类,它具有标准库中的向量容器作为成员。该课程的目的是创建一个线性代数类供我个人使用。

The class is supposed to have a constructor that initializes a vector filled only with zeros and two overloadings of the [] operator to access the data.

该类应该有一个构造函数,初始化一个仅用零填充的向量和[]运算符的两个重载来访问数据。

The code looks as follows:

代码如下:

#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;
}

Apparently, the code compiles correctly, but there is no output from the main function. The problem appears to be in the overloading of the operators and I have been reading in different forums but I haven't been able to find the solution.

显然,代码编译正确,但主函数没有输出。问题似乎是运营商的超载,我一直在不同的论坛阅读,但我一直无法找到解决方案。

Any help is appreciated.

任何帮助表示赞赏。

2 个解决方案

#1


4  

In

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; defines a new variable mVector that shadows the member variable mVector. The local mVector effectively replaces the member mVector and is initialized, loaded with 0s and then discarded when the constructor ends. The member mVector is left default initialized to size zero, causing problems later on when you attempt to access the values you believe you stored.

std :: vector mVector;定义一个新的变量mVector,它隐藏成员变量mVector。本地mVector有效地替换成员mVector并初始化,加载0,然后在构造函数结束时丢弃。成员mVector默认初始化为大小为零,稍后当您尝试访问您认为存储的值时会导致问题。

Instead you could

相反,你可以

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);
    }
}

but std::vector has a constructor that does this work for you, default initializing size elements, that you can take advantage of in the Member Initializer List

但是std :: vector有一个构造函数可以为你工作,默认初始化size元素,你可以在Member Initializer List中利用它

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

Further, since std::vector knows its length, you can remove the mSize member and replace uses of it with mVector.size()

此外,由于std :: vector知道它的长度,你可以删除mSize成员并用mVector.size()替换它的用法

#2


4  

In your constructor, you are declaring a local variable mVector that hides the class member of the same name. So you are populating the local variable, not the class member. You need to remove the local variable:

在构造函数中,您声明了一个隐藏同名类成员的局部变量mVector。所以你填充局部变量,而不是类成员。您需要删除局部变量:

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

Now, that being said, you don't need the loop at all, since std::vector has a resize() method that can fill the vector with values:

现在,话虽如此,你根本不需要循环,因为std :: vector有一个resize()方法,可以使用值填充向量:

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

Alternative, you can use the vector's own constructor instead, which does the same thing:

或者,您可以使用向量自己的构造函数,它执行相同的操作:

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

Either way, the mSize member is redundant, as std::vector has its own size() method that you can use when needed.

无论哪种方式,mSize成员都是多余的,因为std :: vector有自己的size()方法,您可以在需要时使用它。

#1


4  

In

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; defines a new variable mVector that shadows the member variable mVector. The local mVector effectively replaces the member mVector and is initialized, loaded with 0s and then discarded when the constructor ends. The member mVector is left default initialized to size zero, causing problems later on when you attempt to access the values you believe you stored.

std :: vector mVector;定义一个新的变量mVector,它隐藏成员变量mVector。本地mVector有效地替换成员mVector并初始化,加载0,然后在构造函数结束时丢弃。成员mVector默认初始化为大小为零,稍后当您尝试访问您认为存储的值时会导致问题。

Instead you could

相反,你可以

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);
    }
}

but std::vector has a constructor that does this work for you, default initializing size elements, that you can take advantage of in the Member Initializer List

但是std :: vector有一个构造函数可以为你工作,默认初始化size元素,你可以在Member Initializer List中利用它

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

Further, since std::vector knows its length, you can remove the mSize member and replace uses of it with mVector.size()

此外,由于std :: vector知道它的长度,你可以删除mSize成员并用mVector.size()替换它的用法

#2


4  

In your constructor, you are declaring a local variable mVector that hides the class member of the same name. So you are populating the local variable, not the class member. You need to remove the local variable:

在构造函数中,您声明了一个隐藏同名类成员的局部变量mVector。所以你填充局部变量,而不是类成员。您需要删除局部变量:

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

Now, that being said, you don't need the loop at all, since std::vector has a resize() method that can fill the vector with values:

现在,话虽如此,你根本不需要循环,因为std :: vector有一个resize()方法,可以使用值填充向量:

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

Alternative, you can use the vector's own constructor instead, which does the same thing:

或者,您可以使用向量自己的构造函数,它执行相同的操作:

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

Either way, the mSize member is redundant, as std::vector has its own size() method that you can use when needed.

无论哪种方式,mSize成员都是多余的,因为std :: vector有自己的size()方法,您可以在需要时使用它。