コントラスタに引数があるクラスの動的確保

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
遊び人
記事: 42
登録日時: 6年前

コントラスタに引数があるクラスの動的確保

#1

投稿記事 by 遊び人 » 6年前

お世話になっております。
例えば以下のようなプログラムがあったとき、21行目にてクラスの動的確保を行っているのですが、コントラスタに引数が必要な場合、
以下のような書き方などではコンパイルエラーになってしまいます。
どのように書けばエラーにならないのかお教えください(初期化は何行になっても構いません)

コード:

#include <iostream>
#include <random>
using namespace std;

class A {
private:
	int a;
public:
	A(int num) : a(num) { }
	void show_a() { cout << a << endl; }
};

int main()
{
	int test_num = 5;
	A *test;
	random_device rand_num;
	mt19937 mt(rand_num());

	//こ↑こ↓---------------------------
	test = new A[test_num](mt() % 5 + 1);
	//-----------------------------------

	for (int i = 0; i < test_num; i++) {
		test[i].show_a();
	}

	delete[] test;
	return 0;
}

lunnear
記事: 10
登録日時: 6年前

Re: コントラスタに引数があるクラスの動的確保

#2

投稿記事 by lunnear » 6年前

コンストラクタに引数を設定するのではなく、初期化関数を用意して配列を作った後、個々に呼び出せばいい。

遊び人
記事: 42
登録日時: 6年前

Re: コントラスタに引数があるクラスの動的確保

#3

投稿記事 by 遊び人 » 6年前

回答ありがとうございます。
確かにそのようにすればプログラムは動きますね!
動的確保の場合コントラスタに引数があると難しいですか(´・ω・`)

lunnear
記事: 10
登録日時: 6年前

Re: コントラスタに引数があるクラスの動的確保

#4

投稿記事 by lunnear » 6年前

すいませんが自分には動的配列を生成と同時に引数を渡す方法はわからないです。
もしかしたらあるかもしれませんが。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: コントラスタに引数があるクラスの動的確保

#5

投稿記事 by みけCAT » 6年前

生成と同時に初期化をするのはできなそうですが、plaement newというのを使うと(デフォルトコンストラクタで初期化した)後から引数付きのコンストラクタを利用して初期化出来るようです。
その13 引数付きコンストラクを持つクラスの配列を初期化する方法
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

遊び人
記事: 42
登録日時: 6年前

Re: コントラスタに引数があるクラスの動的確保

#6

投稿記事 by 遊び人 » 6年前

どちらにしてもデフォルトコントラスタは作らなければならないようですね・・・
どちらを使用するか迷いますが
以後plaement newを使用させていただきます。
皆さんありがとうございました!

コード:

#include <iostream>
#include <random>
#include <new>
using namespace std;

class A {
private:
	int a;
public:
	A() : a(0) { }
	A(int num) : a(num) { }
	void show_a() { cout << a << endl; }
};

int main()
{
	int test_num = 5;
	A *test;
	random_device rand_num;
	mt19937 mt(rand_num());

	//こ↑こ↓---------------------------
	test = new A[test_num];
	for (int i = 0; i < test_num; i++) {
		new(test + i) A(mt() % 5 + 1);
	}
	//-----------------------------------

	for (int i = 0; i < test_num; i++) {
		test[i].show_a();
	}

	delete[] test;
	return 0;
}

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: コントラスタに引数があるクラスの動的確保

#7

投稿記事 by ISLe » 6年前

遊び人 さんが書きました:どちらにしてもデフォルトコントラスタは作らなければならないようですね・・・
デフォルトコンストラクタは作らなくてもできます。
既存オブジェクトを上書きするのではなく、更地に構築します。

コード:

#include <iostream>
#include <random>
#include <new>
using namespace std;

class A {
private:
    int a;
public:
    A(int num) : a(num) { }
    void show_a() { cout << a << endl; }
};

int main()
{
    int test_num = 5;
    char *buf;
    A **test;
    random_device rand_num;
    mt19937 mt(rand_num());

    buf = new char[sizeof(A) * test_num]; // 配置用メモリ領域確保
    test = new A*[test_num]; // 各オブジェクトへのポインタ
    for (int i = 0; i < test_num; i++) {
        test[i] = new(buf + sizeof(A) * i) A(mt() % 5 + 1);
    }

    for (int i = 0; i < test_num; i++) {
        test[i]->show_a();
    }

    for (int i = 0; i < test_num; i++) {
        test[i]->~A(); // (必要なら)デストラクタは明示的に呼ぶ
    }
    delete[] test;
    delete[] buf;
    return 0;
}

かずま

Re: コントラスタに引数があるクラスの動的確保

#8

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

A *test; のままでもできますよ。

コード:

#include <iostream>
#include <random>
#include <new>
using namespace std;
 
class A {
private:
    int a;
public:
    A(int num) : a(num) { }
    void show_a() { cout << a << endl; }
};
 
int main()
{
    int test_num = 5;
    A *test;
    random_device rand_num;
    mt19937 mt(rand_num());
 
    test = reinterpret_cast<A*>(new char[sizeof(A) * test_num]);
    for (int i = 0; i < test_num; i++)
        new(test + i) A(mt() % 5 + 1);

    for (int i = 0; i < test_num; i++)
        test[i].show_a();

    for (int i = 0; i < test_num; i++)
        test[i].~A();

    delete[] reinterpret_cast<char*>(test);
    return 0;
}

遊び人
記事: 42
登録日時: 6年前

Re: コントラスタに引数があるクラスの動的確保

#9

投稿記事 by 遊び人 » 6年前

デフォルトコントラスタを作らなくてもできる方法があったんですね!
かずまさんのコードが綺麗で個人的に気に入りました。
ポインタって奥が深いですね。

返信

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