動的配列の引数付きコンストラクタの初期化について。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
赤鬼

動的配列の引数付きコンストラクタの初期化について。

#1

投稿記事 by 赤鬼 » 13年前

先ほど包含の件で質問させて頂いたあと、色々弄っていてふと疑問が浮かんだのですが
STLを使った動的配列の引数つきコンストラクタの初期化はどうすれば良いのでしょうか?

コード:

#include <iostream>
#include <vector>
#include <new>
using namespace std;
class A{
public:
	int a;
	A(){
		cout<<"デフォ"<<endl;
	}
	A(int num):a(num){
		cout<<"引数"<<a<<endl;
	}
};
class B{
public:
	vector<A> array;
	B():array(3){						//暗黙の内にデフォルトコンストラクタでA[0]~A[2]が作成される
		vector<A>::iterator it=array.begin();	//placementnewによる配列の置き換えのためのポインタを取得する為のイテレータ
		for(int i=0;i<3;i++)
			new(&*it+i)     A(10+i);
	}
};
最初に思いついたのがこれですが途中ごちゃごちゃしてしまうなぁと思ったので

コード:

//省略
class B{
public:
	vector<A> array;
	B(){
		array.reserve(3);
		for(int i=0;i<3;i++)
			array.push_back(10+i);
	}
};
これぐらいしか思いつきませんでした(こっちの方が処理が早いですかね?)
vectorの文法を調べてみてもそれらしいものが見当たらなかったので
(第二引数まで指定するのは複製なので結局は上か下の処理になってしまいます)
別の書き方はないのでしょうか?

かずま

Re: 動的配列の引数付きコンストラクタの初期化について。

#2

投稿記事 by かずま » 13年前

コード:

#include <iostream>
#include <vector>
#include <new>

using namespace std;

class A {
public:
    int a;
    A() { cout << this << ": A()\n"; }
    A(const A& x) : a(x.a) { cout << this << ": A() copy\n"; }
    A(int num) : a(num) { cout << this << ": A(num = "<< a << ")\n"; }
    ~A() { cout << this << ": ~A()\n"; }
};

class B {
public:
    vector<A> array;
    B() : array(3) {  // array[0] - array[2] are initialized by copy ctor
        vector<A>::iterator it = array.begin();
        for (int i = 0; i < 3; i++)
            new(&*it+i) A(10+i);  // use placement new
    }
};

int main()
{
    B b;
    for (int i = 0; i < 3; i++) cout << ' ' << b.array[i].a;
    endl(cout);
}
実行結果

コード:

0018FEBC: A()
00703A78: A() copy
00703A7C: A() copy
00703A80: A() copy
0018FEBC: ~A()
00703A78: A(num = 10)
00703A7C: A(num = 11)
00703A80: A(num = 12)
 10 11 12
00703A78: ~A()
00703A7C: ~A()
00703A80: ~A()
b.array.a は、デフォルトコンストラクタで初期化された 1個のインスタンスを、
コピーコンストラクタで 3回コピーした後、placemetn new により引数ありコンスト
ラクタで初期化されています。

コード:

#include <iostream>
#include <vector>
#include <new>

using namespace std;

class A {
public:
    int a;
    A() { cout << this << ": A()\n"; }
    A(const A& x) : a(x.a) { cout << this << ": A() copy\n"; }
    A(int num) : a(num) { cout << this << ": A(num = "<< a << ")\n"; }
    ~A() { cout << this << ": ~A()\n"; }
};

class B {
public:
    vector<A> array;
    B() {
        array.reserve(3);
        for (int i = 0; i < 3; i++)
            array.push_back(10 + i);
    }
};

int main()
{
    B b;
    for (int i = 0; i < 3; i++) cout << ' ' << b.array[i].a;
    cout << endl;
}
実行結果

コード:

0018FEF8: A(num = 10)
002F39E0: A() copy
0018FEF8: ~A()
0018FEF8: A(num = 11)
002F39E4: A() copy
0018FEF8: ~A()
0018FEF8: A(num = 12)
002F39E8: A() copy
0018FEF8: ~A()
 10 11 12
002F39E0: ~A()
002F39E4: ~A()
002F39E8: ~A()
b.array.a は、引数ありコンストラクタで初期化されたインスタンスを、
コピーコンストラクタでコピーした後、最初のインスタンスはデストラクトされます。
これを 3回繰り返しています。

赤鬼

Re: 動的配列の引数付きコンストラクタの初期化について。

#3

投稿記事 by 赤鬼 » 13年前

なるほど、デフォルトは一度しか呼び出されて無いんですね。
その後コピーが三回・・・・上の方が見かけ上処理が少ないように見えますが、
デストラクタの処理が無い場合下の方が同等、早いときもあると、状況によって使い分けたほうが良いという事ですか?

閉鎖

“C言語何でも質問掲示板” へ戻る