• 締切済み

vector操作でコピーコンストラクタの抑制

std::vector<std::vector<MyData>> vecvec; とした場合、vecvec.insert() / erase() でも MyData のコピーコンストラクタは走らないのですが、 struct MyVector { std::vector<MyData> vec; }; std::vector<MyVector> vecMyVec; とした場合、vecMyVec.insert() / erase() で、MyData のコピーコンストラクタが走ります。 MyVector が、何らかの継承と実装をすれば、回避できると思うのですが、 その方法を知ってる方がいらしたら教えてください。

みんなの回答

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1

>vecvec.insert() / erase() でも MyData のコピーコンストラクタは走らない これは、MyDataを格納したvectorを、insert/eraseしようとするのですよね? つまり、vecvecは、MyDataを格納したvectorのポインタの格納リストになるわけですね。 入出力対象が、ポインタなので、単に値をコピーするだけですが、vecMyVecの場合は、 MyVectorというクラス(構造体)が入出力対象なので、vector側も渡されたオブジェクトを 自分の領域に格納する時にコピーするしかない。その時に、コピーコンストラクタを使う。 また、vectorの場合は、メモリが連続に配置される必要があるので、eraseを行うと、 eraseした箇所以降のMyVectorオブジェクトを一旦、全てデストラクタで破棄してから、 再度、オブジェクトの生成・コピーをやり直す、その時に、コピーコンストラクタが 使われる…。 コピーコンストラクタだけでなく、デストラクタも何回も呼ばれるんじゃないかと思いますが、どうでしょう? #全然C++をいじってないので、だいぶ忘れていますが。。 というわけで、std::vectorにオブジェクトを格納するときは、コピーコンストラクタは必須。 std::list<MyVector>とかだと、コピーコンストラクタとかデストラクタの呼ばれる回数とかは、変わってくると思いますが。 さて、どんなもんでしょう。 #間違っていたら、つっこんで下さい>皆様 vectorの場合は、メモリを連続領域に配置できないときには、全オブジェクトを破棄して、コピーし直すと思うので、insertやeraseだけでなく、場合によっては、push_backでも、 デストラクタやコピーコンストラクタが動くと思いますよ。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • vectorのresizeについて

    class A{ vector<double> data; public: A(int a){ this->data.resize(a); } }; template<class T> class B { std::vector<T> vec; public: B(int a){ this->vec.resize(a); } }; int main() { B<A> c(10); } としたとき class A のコンストラクタの値を指定することができません. vectorのresizeにコンストラクタの値を指定することができるのでしょうか. また,resize以外にこのようなことをすることができるのでしょうか. 回答よろしくお願いします.

  • C++でSTLのVectorを使った構造体について

    Vectorで作った構造体配列a内でさらにVectorで宣言された配列bを作った場合、bに数値を代入するにはどうすれば良いのでしょうか? struct A {  std::vector<int> b; }; std::vector<A> a;

  • 【.NET】コンストラクタをあとで呼出す方法

    .NET初心者です。 今VB.NETでVB6向けの自作COMクラスライブラリを作成しています。 自作クラスはStreamWriterクラスのラッパークラスとしてStreamWriterと継承関係にあります。 COMは引数なしのコンストラクターを一つ用意しなければなりませんが、 StreamWriterクラスは引数なしのコンストラクタを用意されていないため困っています。 自作クラス自身もFileクラスのラッパークラスで引数として使う必要があるため 継承関係を維持してVB6に公開する必要があります。 この問題をなんとか解決する手法って存在するのでしょうか? ちなみにほかに考えた手法は下記です。 ・プロパティーに StreamWriterのインスタンスを用いて継承関係なしであとでinitメソッドを呼び出す   →Fileラッパークラスの引数でStreamWriter型に代入出来ないため不可 ・StreamWriterを引数に取るメソッドの実装をあきらめる   →極力したくない ・StreamWriterラッパークラスの引数なしコンストラクタでStreamWriterクラスの引数ありコンストラクタを呼ぶ   →後でファイルのパスを指定する方法が見つからないため不可 他言語はそれなりにやってきたのでコンストラクターをあとで呼び出すなんて出来ないのはなんとなくわかるのですが何せ.NETを触り始めたのが最近なのでよろしくお願い致します。

  • C++/CLIの構造体のコンストラクタについて

    C++/CLIの構造体のコンストラクタについて C++/CLIで、固定サイズの配列を持つ構造体を、次のようにコーディングして使っています。 value struct AAA { public:   array<unsigned short>^ m1;   AAA(unsigned short dummy)   {     m1 = gcnew array<unsigned short>(4);   } }; AAA ^struct0 = gcnew AAA(0); この方法で正常に動作するのですが、2点ほど気になる点があります。 (1) コンストラクタAAA(unsigned short dummy)を実装しなくても済む方法がないか? (2) この方法では、struct0を、ネイティブヒープ領域に割り当てられない (AAA *struct0 = new AAA(0))でコンパイルエラー) (1)と(2)は関連する気もするのですが、これらを解決する方法はあるのでしょうか?

  • メンバ変数のサイズを条件に使いたいのですが

    vectorコンテナの中の構造体のメンバ変数のサイズをfor文の条件に使いたいのですが、プログラム実行中にエラーが出てしまいます。 いろいろいじって試してみたのですが、どうしてもわかりませんでした。 コンパイルエラーは出ませんでしたが、こういう事はできないのでしょうか? どなたか助けてください。お願いします。 #include <iostream> #include <string> #include <vector> using namespace std; struct kouzoutai { vector<string> koumoku; }; int main(){ vector<kouzoutai> vec; vec[0].koumoku[0] = string("aiueo"); vec[0].koumoku[1] = string("kakiku"); for (vector<string>::size_type i=0; i != vec[0].koumoku.size() ; i++){} }

  • ベクターの初歩について

    ベクターについて勉強し始めた所です。ベクターについて解らない事があるので教えて下さい。 今ベクターに10個数字を登録します。 後で3か5があれば取り除きます。 #include <vector> #include <iostream> int main(){   using namespace std;   vector<int> array1;   for( int i = 0; i < 10; ++i )     array1.push_back( i );   vector<int>::iterator it;   for(it = array1.begin(); it != array1.end(); ){     if(*it == 3 || *it==5)       it = array1.erase(it);     else       ++it;   }   for( it = array1.begin(); it != array1.end(); ++it )     cout << *it << endl;   return 0; } 一応出来たんですが、これが構造体だったらどうしたらいいのでしょう? typedef struct{   int x,y; }xy_t; vector<xy_t> array1; だとして、最初にx,yのそれぞれ10個に適当な値を入れておき、xが3か5ならそれを削除するにはどうしたらいいのでしょうか。 また、一つずつ削除する方法と、remove関数で出来そうな気がするので、もし一括で出来る方法があればそちらも2種類お願いします。 (構造体を用いたベクターの使い方が書いてある参考サイトでも結構です) XP Pro VS2005Pro よろしくお願いします。

  • 別の型の作成について

    C/C++言語におけるtypedefの役割は「別名の型」を作成することですが、 「別の型」を作成することはできるでしょうか? 継承を使えば実装可能ですが、 継承元クラスにコンストラクタがあった場合、 継承先からいちいち呼び出すのがとても面倒です。 できればマクロに頼らずに実装したいのですが、 何か標準化された、もしくは近い実装方法はありますか?

  • min_elementの三番目の引数

    ただいまSTLを勉強しているのですが、min_elementの三番目の引数の意味がわかりません。 iter min_element(iter first,iter last,pred pr); 以下のように使うのかなと自己解釈しましたが違うようです。 どうかご教授お願いします。 struct DATA{ int a; int b; }; main() { std::vector< DATA > data_vec; std::vector< DATA >::iterator it; for(int i=0;i<10;i++)//適当な数を10個プッシュバック { DATA data; data.a=rand(); data.b=rand(); data_vec.push_back(data); } //it = min_element(data_vec.begin(),data_vec.end(),DATA::a); }

  • listをvectorにコピーするときに

    例えば #include<iostream> #include<vector> #include<list> using namespace std; void main(void) { unsigned pos; list<unsigned> lu; list<unsigned>::iterator p; vector<unsigned> vu; for(lu.clear(),pos=0;pos<9;lu.push_back(pos++)); for(p=lu.begin();p!=lu.end();cout<<*p++); cout<<endl; vu=vector(lu); //error for(pos=0;pos<vu.size();cout<<vu[pos++]); cout<<endl; } とするとエラーになるため//errorのかわりに vu.clear(); vu.insert(vu.begin(),lu.begin(),lu.end()); としていますが少し不細工です 他に方法はあるのでしょうか?

  • VHDLのvector

    VHDLにおいて「vector(5bitとします)の全bitが'0'である場合」という条件のif文を書く場合、if(Data = "00000") then と記述する以外に方法はありませんか? ここでは Data :in std_logic_vector(4 downto 0); としています。 5bitくらいならまだいいですが、16bitなどでもひたすら'0'を羅列するしかないのでしょうか?よろしくお願いします。