インスタンス変数として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
はオブジェクトであるため、不正です。
2番目のオプション:
vector<int> temp(size,0);
vec = temp;
コンパイルはされますが、余分な作業は無駄に行われます。割り当てに到達するまでに、2つのベクトルはすでに構築され、その後破棄されます。
ベクトルの使用はクラスで合法ですが、問題はそれをどのように初期化するかです。
#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)
{}
最後に、コメンターの1人が指摘しているように、ベクトルが構築されるとサイズは実際には必要ありません。したがって、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
// 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