简体   繁体   English

在类构造函数中设置 std::vector

[英]Setup std::vector in class constructor

I'm designing a class that has a std::vector<int> as an instance variable.我正在设计一个将std::vector<int>作为实例变量的类。 I'm using a std::vector because I need to set its size at runtime.我使用std::vector是因为我需要在运行时设置它的大小。 Here are the relevant portions of my code:以下是我的代码的相关部分:

my_class.h:

#include <vector>
using std::vector;
class MyClass {
    int size;
    vector<int> vec;
}

my_class.cc:

#include "my_class.h"
using std::vector
MyClass::MyClass(int m_size) : size(m_size) {
     vec = new vector<int>(size,0);
}

When I attempt to compile I get these error messages:当我尝试编译时,我收到以下错误消息:

g++ -c -Wall my_class.cc -o my_class.o

my_class.cc: In constructor ‘MyClass::MyClass(int):

  my_class.cc:4 error: no match for ‘operator=’ in ‘((MyClass*)this)->My_Class::vec = ((*(const allocator_type*)(& std::allocator<int>())), (operator new(24u), (<statement>, ((std::vector<int>*)<anonymous>))))’

make: *** [my_class.o] Error 1

However, when I change the offending line to:但是,当我将违规行更改为:

vector<int> temp(size,0);
vec = temp;

It now compiles without a hitch and I get the desired behavior and can access my vector as它现在可以顺利编译,我得到了所需的行为,并且可以访问我的向量

vec[i]  // i having been defined as an int yada yada yada

This workaround is okay, but I would like to understand why it works and the first method fails.这种解决方法没问题,但我想了解它为什么有效而第一种方法失败。 Thanks in advance.提前致谢。

Just do:做就是了:

MyClass::MyClass(int m_size) : size(m_size), vec(m_size, 0)

You already seem to know about initializer lists, why not initialize vector there directly?您似乎已经了解初始化列表,为什么不直接在那里初始化向量?

vec = new vector<int>(size,0);

is illegal because new returns a pointer and in your case vec is an object.是非法的,因为new返回一个指针,而在您的情况下vec是一个对象。

Your second option:你的第二个选择:

vector<int> temp(size,0);
vec = temp;

although it compiles, does extra work for no gain.尽管它可以编译,但做额外的工作却没有任何收获。 By the time you reach the assignment, two vectors would already have been constructed and discarded afterwards.当你完成任务时,两个向量已经被构建并随后被丢弃。

The use of vector is legal in your class, the problem is how you initialize it:在你的班级中使用 vector 是合法的,问题是你如何初始化它:

#include <vector>

class MyClass {
public:
    MyClass(int m_size);

    // ... more things...
private:
    int size;
    vector<int> vec;
}

You are assigning a pointer to a new vector object, as if this vector object was not initialized.您正在分配一个指向新向量对象的指针,就好像该向量对象未初始化一样。

vec = new vector<int>(size,0);

If you really want this to work, then you should declare your vec object as:如果你真的想让它工作,那么你应该将你的vec对象声明为:

vector<int> * vec;

And don't forget to add a destructor:并且不要忘记添加一个析构函数:

MyClass::~MyClass {
    delete vec;
}

Why did it work when you dropped the new particle?为什么当你放下new粒子时它会起作用? Because you are creating a new object vector , and overwriting the one in your class (this does not guarantee the original one to be correctly eliminated, however).因为您正在创建一个新的对象vector ,并覆盖您班级中的对象(但是,这并不能保证正确消除原始对象)。

You actually don't need to do that.你实际上不需要这样做。 Your vector object is already initialized (its default constructor called) when you've reached the constructor of MyClass.当您到达 MyClass 的构造函数时,您的vector对象已经初始化(调用了它的默认构造函数)。 If you just want to be sure that memory is reserved for size items:如果您只想确保为size项目保留内存:

MyClass::MyClass(int m_size): size(m_size) {
    vec.reserve( size );
}

If you want your vector to have size elements, then:如果您希望您的矢量具有size元素,则:

MyClass::MyClass(int m_size): size(m_size), vec(m_size, 0)
    {}

Finally, as one of the commenters points out, size is not actually needed once the vector has been constructed.最后,正如一位评论者指出的那样,一旦构建了向量,实际上就不需要大小了。 So you can get rid of the size member:所以你可以摆脱size成员:

class MyClass {
public:
    MyClass(int m_size): vec(m_size, 0)
        {}

    unsigned int getSize() const
        { return vec.size(); }

    // ... more things...
private:
    vector<int> vec;
}

Hope this helps.希望这可以帮助。

#include <vector>
#include <iostream>
#include <string>
#include <typeinfo>

using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::to_string;

class Parse
{
private:
    string         m_str;
    vector<string> m_vec;
public:
    // Constructor with all defaults (1 of 4 constructors)
    Parse(){ 
        cout << "\ncreating class with all default values\n";
        m_str = "";
        m_vec.push_back("");    
    }

    // Constructor with all cases used
    Parse  (string         &tmp_str,
            vector<string> tmp_vec):

            m_str          (tmp_str),
            m_vec          (tmp_vec)
    {
        cout << "Your vector contains " + to_string(m_str.size()) + " arguments\n";
    }

    // Constructor with other contents given but not vector
    Parse  (string         &tmp_str): 
            m_str          (tmp_str)
    {
        m_vec.push_back("");
    }
    // Constructor with only Vector given but not other contents
    Parse  (vector<string>   tmp_vec):
            m_vec           (tmp_vec)
    {
        m_str = "";
    }

    string get_str_var(){return m_str;}

    void classed_print_vector_strings()
    {
        for (string i : m_vec){ cout << i << " \n";}
    }

};



// rm ./class_vector; g++ class_vector.cpp -o class_vector -std=c++17; ./class_vector arg1 arg2 arg3

int main(int argc, char *argv[])
{
    // turn **argv to a vector
    vector<string> args(argv, argv + argc);
    // iterate from argv through argv+argc

    // initialize with default arguments.
    Parse tracker1;
    // initalize with all used arguments
    Parse tracker2(args[0], args);
    // initalize with only the vector
    Parse tracker3(args);
    // initalzie without the vector, but with another arg
    Parse tracker4(args[0]);

    cout << "\nTracker 1 ---------------------\n";
    tracker1.classed_print_vector_strings();
    cout << "\nTracker 2 ---------------------\n";
    tracker2.classed_print_vector_strings();
    cout << "\nTracker 3 ---------------------\n";
    tracker3.classed_print_vector_strings();
    cout << "\nTracker 4 ---------------------\n";
    tracker4.classed_print_vector_strings();


    return 0;
}
rm ./class_vector; g++ class_vector.cpp -o class_vector -std=c++17; ./class_vector arg1 arg2 arg3

This will show you how to create a class that will give you the option to initialize the class with or without the vector with other arguments present and/or not present.这将向您展示如何创建一个类,该类将为您提供使用或不使用向量以及存在和/或不存在其他参数来初始化类的选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM