繁体   English   中英

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

[英]Setup std::vector in class constructor

我正在设计一个将std::vector<int>作为实例变量的类。 我使用std::vector是因为我需要在运行时设置它的大小。 以下是我的代码的相关部分:

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

当我尝试编译时,我收到以下错误消息:

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

但是,当我将违规行更改为:

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

它现在可以顺利编译,我得到了所需的行为,并且可以访问我的向量

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

这种解决方法没问题,但我想了解它为什么有效而第一种方法失败。 提前致谢。

做就是了:

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

您似乎已经了解初始化列表,为什么不直接在那里初始化向量?

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

是非法的,因为new返回一个指针,而在您的情况下vec是一个对象。

你的第二个选择:

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

尽管它可以编译,但做额外的工作却没有任何收获。 当你完成任务时,两个向量已经被构建并随后被丢弃。

在你的班级中使用 vector 是合法的,问题是你如何初始化它:

#include <vector>

class MyClass {
public:
    MyClass(int m_size);

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

您正在分配一个指向新向量对象的指针,就好像该向量对象未初始化一样。

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

如果你真的想让它工作,那么你应该将你的vec对象声明为:

vector<int> * vec;

并且不要忘记添加一个析构函数:

MyClass::~MyClass {
    delete vec;
}

为什么当你放下new粒子时它会起作用? 因为您正在创建一个新的对象vector ,并覆盖您班级中的对象(但是,这并不能保证正确消除原始对象)。

你实际上不需要这样做。 当您到达 MyClass 的构造函数时,您的vector对象已经初始化(调用了它的默认构造函数)。 如果您只想确保为size项目保留内存:

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

如果您希望您的矢量具有size元素,则:

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

最后,正如一位评论者指出的那样,一旦构建了向量,实际上就不需要大小了。 所以你可以摆脱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;
}

希望这可以帮助。

#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

这将向您展示如何创建一个类,该类将为您提供使用或不使用向量以及存在和/或不存在其他参数来初始化类的选项。

暂无
暂无

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

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