C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: C++でインスタンス生成する方法について


(過去ログ 84 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■49801 / inTopicNo.1)  C++でインスタンス生成する方法について
  
□投稿者/ デザパタ (11回)-(2010/05/18(Tue) 10:05:31)

分類:[C/C++] 

ちょっといいたことがなんなのか伝わりづらいかもしれませんが、
C++で
const T test = 1.0f;
というような記述を見かけました。
Tはクラスで、const float型の引数を取るコンストラクタを持っています。
で、上記のように書くとそのコンストラクタが呼ばれているようなのですが、
どうしてこのような書き方ができるのでしょうか?その仕様が知りたいのですがわかりません。
(Tで代入演算子をオーバーロードしているような記述は見当たりませんでした)

以下現状の私の考え。
普通なら以下のように書くかと思います。
T test = new T(1.0f);
一番上の記述でnew がいらないのはTの前にconstがついているからで、
スタックに確保されることになると解釈しています。
const T test = (T)1.0f;
こういう解釈でいいんですかねぇ。
でもこれでなぜコンストラクタが呼ばれるのか・・・わかりません。
引用返信 編集キー/
■49802 / inTopicNo.2)  Re[1]: C++でインスタンス生成する方法について
□投稿者/ 774RR (504回)-(2010/05/18(Tue) 10:22:24)
うーん。そういう仕組みだから・・・で納得しない?いや、説明しても別にいいんだけど。

int i=1; と書けるなら myclass x=1; と書けてもいいぢゃん。
上記は int i(1); と書けるし myclass x(1); とも書けるよん。

引用返信 編集キー/
■49803 / inTopicNo.3)  Re[1]: C++でインスタンス生成する方法について
□投稿者/ aetos (292回)-(2010/05/18(Tue) 10:25:27)
No49801 (デザパタ さん) に返信
> ちょっといいたことがなんなのか伝わりづらいかもしれませんが、
> C++で
> const T test = 1.0f;
> というような記述を見かけました。
> Tはクラスで、const float型の引数を取るコンストラクタを持っています。
> で、上記のように書くとそのコンストラクタが呼ばれているようなのですが、
> どうしてこのような書き方ができるのでしょうか?その仕様が知りたいのですがわかりません。
> (Tで代入演算子をオーバーロードしているような記述は見当たりませんでした)

そういう決まりだからですとしか言いようがありません。
const の有無は関係ありません。
仕様を知りたければ言語規格書を見ましょう。
JISC のサイト
http://www.jisc.go.jp/
で「JIS検索」→「X3014」と入力で C++ の規格書が閲覧できます。
# 今はメンテナンス中だとかで、仕様書のどの辺を見ればいいかはちょっとわかりませんでした。
引用返信 編集キー/
■49805 / inTopicNo.4)  Re[2]: C++でインスタンス生成する方法について
□投稿者/ デザパタ (12回)-(2010/05/18(Tue) 11:26:00)
ありがとうございます。

うわ、ほんとですね。
キャストできるコンストラクタがあればconstとか関係なくできるんですね。
ということは
T test = 1.0f;
test = 2.0f;
と書いたら、2回newされて1回目の1.0fの方のメモリが回収できなくなってしまうということでしょうか?

少し質問は変わるかもしれませんが、組み込みとかだとメモリを動的確保したくないときがあるかと思います。
スタックにオブジェクトの実体を置きたいときはどのようにするのでしょうか?
私はTの前のconstがその役割を果たしているのかなと思ったのですが。
でもそうするとtestに次の代入ができなくなってしまいますし・・・。

引用返信 編集キー/
■49808 / inTopicNo.5)  Re[3]: C++でインスタンス生成する方法について
□投稿者/ 774RR (505回)-(2010/05/18(Tue) 12:05:57)
他の言語での挙動を勝手に C++ にあてはめているような気がする。
「一時オブジェクト」というものを理解する必要がありそうだね。
# なんというか C++ の罠にはまっている典型的パターンと思われる
# explicit とかその辺の理解も必要になってきているわけだ

掲示板のスペースで説明するにはいささか分量が多すぎると思われるが
void hogehoge() {
 int i=1;
 i=2;
} // としてメモリリークなんかしないのと同様
void piyopiyo() {
 myclass x=1.0f;
 x=2.0f;
} // としたってメモリリークしないよ (myclass 自体にリークバグがあれば別だが)

C++ 言語仕様書に「スタック上にメモリを確保する」などという文言は一切現れない。
そういう詳細は各処理系の実装に任されているのでマニュアルを読む必要がある。

> スタックにオブジェクトの実体を置きたいときはどのようにするのでしょうか?
組み込み系に限らず、ふつーは { ... } の中に書かれた変数(インスタンス)のための
記憶域(まあ端的にはメモリ)は、スタック上にとられるもんだ。
const の有無とかは関係ない
引用返信 編集キー/
■49813 / inTopicNo.6)  Re[4]: C++でインスタンス生成する方法について
□投稿者/ デザパタ (13回)-(2010/05/18(Tue) 13:24:23)
No49808 (774RR さん) に返信
> 他の言語での挙動を勝手に C++ にあてはめているような気がする。
> 「一時オブジェクト」というものを理解する必要がありそうだね。
> # なんというか C++ の罠にはまっている典型的パターンと思われる
> # explicit とかその辺の理解も必要になってきているわけだ
>
> 掲示板のスペースで説明するにはいささか分量が多すぎると思われるが
> void hogehoge() {
>  int i=1;
>  i=2;
> } // としてメモリリークなんかしないのと同様
> void piyopiyo() {
>  myclass x=1.0f;
>  x=2.0f;
> } // としたってメモリリークしないよ (myclass 自体にリークバグがあれば別だが)
>
> C++ 言語仕様書に「スタック上にメモリを確保する」などという文言は一切現れない。
> そういう詳細は各処理系の実装に任されているのでマニュアルを読む必要がある。
>
>>スタックにオブジェクトの実体を置きたいときはどのようにするのでしょうか?
> 組み込み系に限らず、ふつーは { ... } の中に書かれた変数(インスタンス)のための
> 記憶域(まあ端的にはメモリ)は、スタック上にとられるもんだ。
> const の有無とかは関係ない


あ、なんかかなり勘違いしてる自覚が出てきました。
■49801で書いた
T test = new T(1.0f);
って間違いでほんとは
T* test = new T(1.0f);
ですね。
全ての謎が解けました。

みなさんどうもありがとうございます。

解決済み
引用返信 編集キー/
■49817 / inTopicNo.7)  Re[5]: C++でインスタンス生成する方法について
□投稿者/ 774RR (506回)-(2010/05/18(Tue) 15:13:52)
うむ、それで謎が解けたのであればさらに追加して言っておくべきことはないのだが
あえて蛇足を加えるならば explicit というキーワードについて調べておくといいかも。

test = 2.0f; // がソースコードの書き方として本来エラーになるべきである
のであれば explicit がきわめて有効。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -