質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

8138閲覧

グローバルスコープを持つインスタンスの初期化について

allmod

総合スコア13

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2018/12/31 14:41

グローバルスコープを持つインスタンスを生成したいのですが、クラスの初期化は関数内で行いたいため記述に悩んでいます。

以下のコードのように、引数を持つコンストラクタを持つクラスをグローバル変数として定義するためには、どのようにしたらよいでしょうか?

例えば、swiftでいう「?」に類する機能や、クラスの定義とコンストラクタの実行タイミングを制御する方法などないのでしょうか?
https://qiita.com/Ryosuke-Hujisawa/items/d4d5fe1b79a804b304f6

c++

1#include <iostream> 2 3class MyClass{ 4 private: 5 int val; 6 public: 7 // コンストラクタ 8 MyClass(int newval) : val(newval){}; 9 // 結果確認用 10 void show(){ 11 std::cout << val << "\n"; 12 } 13}; 14 15MyClass cls; // <- コンストラクタに入力値がないためエラー 16 17int main(){ 18 // クラスの初期化 19 // cls(1);? 20 // もちろんここでMyClass cls(1);と書けばローカル内で定義できることはわかるのですが、 21 // pybind11を用いてpythonでラップしたいため、グローバルスコープで定義したいのです。 22 23 // 結果の確認 24 cls.show(); 25}
dodox86👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ここなんてどうでしょうか!

投稿2018/12/31 15:42

編集2018/12/31 15:47
alphya

総合スコア124

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

allmod

2018/12/31 16:46

pybind11の解説ですね。参考になります。ありがとうございます。 簡単な例ではドキュメントを読んで実装できたのですが、今実装しようとしているものは自作クラスを引数としていたりと少し複雑なため、元の質問の内容を解決したいのです。
alphya

2018/12/31 16:52

すみません><
guest

0

引数のないコンストラクタを追加するのはだめですか?  で、valには初期値を入れる。

投稿2018/12/31 15:24

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

allmod

2018/12/31 16:25 編集

ご回答ありがとうございます。 質問のため簡潔に書きましたが、MyClassと記載したクラスはほかの開発者によるライブラリによって書かれているそこそこ大きなクラスでして、今後の保守も考えるとなるべく手を付けたくないのです。継承によってコンストラクタを書き換えられればよいのですが、調べた範囲ではC++では継承を行っても親クラスのコンストラクタを呼び出す必要があり引数のないコンストラクタを追加することができませんした(間違っていましたらご指摘いただけると幸いです)。 ただ他に置き換える方法がないのでしたら、ご教授いただいたように引数のないコンストラクタとパラメータを設定するメンバ関数を追加するなどライブラリのコードを直接書き換えたいと思います。 説明が足らず後出しでの条件付けとなってしまいまして申し訳ありません。
guest

0

ベストアンサー

単にglobal scopeでMyClass cls(1);と書けばいいのでは


追記

ポインタで持つのではだめですか?

投稿2018/12/31 15:13

編集2018/12/31 15:32
yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

allmod

2018/12/31 15:27 編集

ご回答ありがとうございます。説明が足らず申し訳ありません。 最終的にはPythonでラップをしたいので、Pythonとのインターフェイスとなるmain関数内(実際にラップする際には関数名をmainからfuncなどに書き換えますが)で初期化したいのです。 (Pythonでラップをするコード自体を質問しようかとも思ったのですが、今回の内容を解決したい場合がC++を書いていると度々あったので、今回の質問の形式にさせていただきました)
allmod

2018/12/31 16:41

追記ありがとうございます! ポインタで持つというのは以下のような書き方でよろしいでしょうか?(よりベターな記述方法などがありましたらご指摘いただけると助かります) 確かにこの書き方ですとうまくできました。ポインタで定義した場合には、コンストラクタの実行はnewで定義したときに行われるため、調整できるということでしょうか。ありがとうございました。 ``` #include <iostream> class MyClass{ protected: int val; public: MyClass(int newval) : val(newval){}; void set(int newval){ val = newval; } void show(){ std::cout << val << "\n"; } }; MyClass *cls; int main(){ cls = new MyClass{1}; cls->show(); } ```
alphya

2019/01/01 01:53

(delete忘れを防ぐために、スマートポインタを使う手段もあります!)
yumetodo

2019/01/01 03:39

というか必ずスマートポインタを使いましょう(書けばよかった
allmod

2019/01/02 03:17

> alphya ご指摘ありがとうございます。確かにdeleteが抜けていましたね; スマートポインタを使って書き直してみました。 ``` #include <iostream> #include <memory> class MyClass{ protected: int val; public: MyClass(int newval) : val(newval){}; void set(int newval){ val = newval; } void show(){ std::cout << val << "\n"; } }; std::unique_ptr<MyClass> cls; void init(){ // $(version) < c++14 // cls.reset(new MyClass(10)); // $(version) >= c++14 cls = std::make_unique<MyClass>(10); } void show(){ cls->show(); } int main(){ init(); show(); } ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問