合計 昨日 今日

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

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: 遊び人
[URL]
ぴよぴよ(920 ポイント)
Date: 2017年10月07日(土) 21:06
No: 1
(OFFLINE)

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

お世話になっております。
例えば以下のようなプログラムがあったとき、21行目にてクラスの動的確保を行っているのですが、コントラスタに引数が必要な場合、
以下のような書き方などではコンパイルエラーになってしまいます。
どのように書けばエラーにならないのかお教えください(初期化は何行になっても構いません)
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#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;
}

Name: lunnear
[URL]
ぴよぴよ(244 ポイント)
Date: 2017年10月07日(土) 23:11
No: 2
(OFFLINE)

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

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

Name: 遊び人
[URL]
ぴよぴよ(920 ポイント)
Date: 2017年10月07日(土) 23:30
No: 3
(OFFLINE)

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

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

Name: lunnear
[URL]
ぴよぴよ(244 ポイント)
Date: 2017年10月08日(日) 00:10
No: 4
(OFFLINE)

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

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

Name: みけCAT
[URL]
伝説なるハッカー(683,511 ポイント)
Date: 2017年10月08日(日) 00:16
No: 5
(OFFLINE)

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

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

Name: 遊び人
[URL]
ぴよぴよ(920 ポイント)
Date: 2017年10月08日(日) 01:47
No: 6
(OFFLINE)

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

[解決!]

どちらにしてもデフォルトコントラスタは作らなければならないようですね・・・
どちらを使用するか迷いますが
以後plaement newを使用させていただきます。
皆さんありがとうございました!
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#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;
}

Name: ISLe
[URL]
ハッカー(265,720 ポイント)
Date: 2017年10月08日(日) 18:11
No: 7
(OFFLINE)

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

遊び人 さんが書きました:どちらにしてもデフォルトコントラスタは作らなければならないようですね・・・

デフォルトコンストラクタは作らなくてもできます。
既存オブジェクトを上書きするのではなく、更地に構築します。

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#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;
}

Name: かずま
[URL]
Date: 2017年10月09日(月) 04:03
No: 8
(OFFLINE)

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

A *test; のままでもできますよ。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#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;
}

Name: 遊び人
[URL]
ぴよぴよ(920 ポイント)
Date: 2017年10月09日(月) 15:57
No: 9
(OFFLINE)

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

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


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[23人]