C++ 在类构造函数中设置 std::vector
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11415469/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setup std::vector in class constructor
提问by fenkerbb
I'm designing a class that has a std::vector<int>
as an instance variable. I'm using a std::vector
because I need to set its size at runtime. Here are the relevant portions of my code:
我正在设计一个具有std::vector<int>
作为实例变量的类。我使用 a 是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);
}
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.
这种解决方法没问题,但我想了解为什么它有效而第一种方法失败。提前致谢。
回答by Luchian Grigore
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.
尽管它可以编译,但做额外的工作却没有任何收获。当你完成任务时,两个向量已经被构建并随后被丢弃。
回答by Baltasarq
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? Because you are creating a new object vector
, and overwritingthe one in your class (this does not guarantee the original one to be correctly eliminated, however).
为什么当你放下new
粒子时它会起作用?因为您正在创建一个新对象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. If you just want to be sure that memory is reserved for size
items:
你实际上不需要这样做。vector
当您到达 MyClass 的构造函数时,您的对象已经初始化(调用了它的默认构造函数)。如果您只想确保为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.
希望这可以帮助。
回答by Scourge
#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 initilize the class with or without
// the vector with other arguments present and/or not present.
// My Background. . .
// github.com/Radicalware
// Radicalware.net
// https://www.youtube.com/channel/UCivwmYxoOdDT3GmDnD0CfQA/playlists