回答編集履歴

5

'---'がついたままだった。

2016/02/06 19:15

投稿

raccy
raccy

スコア21735

test CHANGED
@@ -39,8 +39,6 @@
39
39
  上記の記述にあるように参照が生き残っている間は、テンポラリオブジェクトは破棄されず、使い続ける事が出来ます。C++標準の仕様ですので、**使ってはいけないわけではありません。**ただ、混乱の元になりそうですので、ムーブコンストラクタを実装して、通常のオブジェクトとして変数を確保し、寿命をはっきりさせた方が良いでしょう。
40
40
 
41
41
 
42
-
43
- ---
44
42
 
45
43
  ###そもそもオブジェクトの破棄とはアクセスできなくなることではない
46
44
 

4

constの左辺値参照を追加し、整理しました。

2016/02/06 19:15

投稿

raccy
raccy

スコア21735

test CHANGED
@@ -1,36 +1,50 @@
1
+ ###Visual Studioの言語拡張でした
2
+
1
3
  Visual Studioで動作を確認しました。どうやら、最初に思っていたのと違ったようです。
2
4
 
3
5
 
4
6
 
5
- 問題なく動作するのは**Visual Studioの言語拡張**であり、標準のC++としては**違反**になります。"/W4"で警告レベルを上げると警告が表示され、"/Za"で言語拡張を無効化するとエラーになります。
6
-
7
- [Temporary Objects Can be Bound to Non-Const References | Microsoft Connect](https://connect.microsoft.com/VisualStudio/feedback/details/807118/temporary-objects-can-be-bound-to-non-const-references)
8
-
9
- [c++ - Non-const reference bound to temporary, Visual Studio bug? - Stack Overflow](http://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug)
10
-
11
- [c++ - Visual Studio is not creating temporary object when typecasting? - Stack Overflow](http://stackoverflow.com/questions/28402173/visual-studio-is-not-creating-temporary-object-when-typecasting)
12
-
13
- [コンパイラの警告 (レベル 4) C4239](https://msdn.microsoft.com/ja-jp/library/186yxbac.aspx)
7
+ 問題なく動作するのは**Visual Studioの言語拡張**であり、標準のC++としては**違反**になります。"/W4"で警告レベルを上げると警告が表示され、"/Za"で言語拡張を無効化するとエラーになります。下記を参考にして下さい。(拡張としては、constありと同じように寿命が延びるようになるようです。constありの場合の話は後述。)
14
8
 
15
9
 
16
10
 
17
- C++標準ではないVisual Studio特有の仕様ですので、Visual Studioを**永遠に使い続ける**のであれば問題ありません。他のコンパイラでも動作できるように移植する予定であれば、そのような記述は避けるべきでしょう。
11
+ * [Temporary Objects Can be Bound to Non-Const References | Microsoft Connect](https://connect.microsoft.com/VisualStudio/feedback/details/807118/temporary-objects-can-be-bound-to-non-const-references)
12
+
13
+ * [c++ - Non-const reference bound to temporary, Visual Studio bug? - Stack Overflow](http://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug)
14
+
15
+ * [c++ - Visual Studio is not creating temporary object when typecasting? - Stack Overflow](http://stackoverflow.com/questions/28402173/visual-studio-is-not-creating-temporary-object-when-typecasting)
16
+
17
+ * [コンパイラの警告 (レベル 4) C4239](https://msdn.microsoft.com/ja-jp/library/186yxbac.aspx)
18
18
 
19
19
 
20
20
 
21
- 修正前話は今回ではとは言えないので、一般的話だと思って下さい
21
+ C++標準ではないVisual Studio特有仕様ですVisual Studioを**永遠に使い続ける**のであれば問題ありません。他のコンパイラでも動作できるように移植する予定であれば、このような記述避けるべきでしょ。こままはClangやGCCではエラーになってコンパイルできません
22
+
23
+
24
+
25
+ ###constな左辺値参照はテンポラリオブジェクトの寿命を延ばす
26
+
27
+ `const CBase& base = CBase();`とconstがついている場合は(メンバー関数もconstにする必要がありますが)、参照が存在する間だけオブジェクトの寿命が延びるため、標準のC++として**問題ありません**。これは式が終了しても、テンポラリオブジェクトが破棄されない例外の一つです。
28
+
29
+
30
+
31
+ 参考: [Object lifetime - cppreference.com](http://en.cppreference.com/w/cpp/language/lifetime#Temporary_object_lifetime)
32
+
33
+ > The lifetime of a temporary object may be extended by binding to a const lvalue reference __or to an rvalue reference (since C++11)__, see [reference initialization](http://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary) for details.
34
+
35
+ > constな左辺値参照__または右辺値参照(C++11から)__に紐付けられる場合、テンポラリオブジェクトの寿命は延長され得る。詳しくは[参照の初期化](http://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary)を見よ。
36
+
37
+
38
+
39
+ 上記の記述にあるように参照が生き残っている間は、テンポラリオブジェクトは破棄されず、使い続ける事が出来ます。C++標準の仕様ですので、**使ってはいけないわけではありません。**ただ、混乱の元になりそうですので、ムーブコンストラクタを実装して、通常のオブジェクトとして変数を確保し、寿命をはっきりさせた方が良いでしょう。
22
40
 
23
41
 
24
42
 
25
43
  ---
26
44
 
27
- 【修正前】
45
+ ###そもそもオブジェクトの破棄とはアクセスできなくなることではない
28
46
 
29
- Clang 700.1.81GCC 5.3.0ではエラーになってパイルでせんね
30
-
31
-
32
-
33
- さて、テンポラリオブジェクトが破棄されると言っても、テンポラリオブジェクトによって使われていたスタック上のメモリ領域が0埋めされるとか、そういうことではありません。スタック上に確保されたメモリ領域は、他に再利用されない限りそのままであり、**無理矢理使用することは可能です**。しかし、言語の仕様上、その領域がいつまでそのままになっているかは一切保証がありません。つまり、**このメモリ領域はもう使う予定は無いから再利用してもいいよ**というのが、**破棄**です。例えば、`base.Show();`の前に何か処理を追加してみて下さい。それだけでテンポラリオブジェクトに使っていたスタック上のメモリ領域が上書きされ、おかしな事が起きる可能性があります。これは、関数が終わった後に破棄されたローカル変数や、deleteやfreeでのメモリ解放でも同じ事が言えます。
47
+ さて、話は変わりますが、テンポラリオブジェクトが破棄されると言っても、テンポラリオブジェクトによって使われていたスタック上のメモリ領域が0埋めされるか、該当メモリ領域へのアクセスが拒否が起きるとか、そういうことではありません。スタック上確保されたメモリ領域は、他に再利用されい限りそのままであり、**無理矢理使用することは可能です**。しかし、言語の仕様上、その領域がいつまでそのままになっているかは一切保証がありません。つまり、**このメモリ領域はもう使う予定は無いから再利用してもいいよ**というのが、寿命がつきて**破棄**されるということです。もし、破棄された後とその利用の間に何か別の処理を追加してあった場合、それだけでテポラリオブジェクトに使っていたスタック上のメモリ領域が上書きされ、おかしな事が起きる可能性があります。これは、関数が終わった後に破棄されたローカ変数や、deleteやfreeのメモリ解放でも同じ事が言え
34
48
 
35
49
 
36
50
 
@@ -38,21 +52,33 @@
38
52
 
39
53
 
40
54
 
41
- 参考: deleteしても使えてしまう例。こっちClang/GCCでもコンパイルできいます。
55
+ 参考: deleteしても使えてしまう例。何が起るかはコンパイラやオプションによっ異なります。
42
56
 
43
57
  ```C++
44
58
 
45
59
  #include <iostream>
46
60
 
61
+ #include <string>
62
+
47
63
 
48
64
 
49
65
  class CBase {
50
66
 
67
+ private:
68
+
69
+ std::string show;
70
+
51
71
  public:
72
+
73
+ CBase() {
74
+
75
+ show = "Show";
76
+
77
+ };
52
78
 
53
79
  void Show() {
54
80
 
55
- std::cout << "Show" << std::endl;
81
+ std::cout << show << std::endl;
56
82
 
57
83
  }
58
84
 
@@ -62,9 +88,11 @@
62
88
 
63
89
  int main() {
64
90
 
65
- CBase *base = new CBase();
91
+ auto base = new CBase();
66
92
 
67
93
  delete base;
94
+
95
+ auto pstr = new std::string("None");
68
96
 
69
97
  base->Show();
70
98
 

3

ちゃんと調べたら、VSの言語拡張でした。

2016/02/06 19:14

投稿

raccy
raccy

スコア21735

test CHANGED
@@ -1,3 +1,31 @@
1
+ Visual Studioで動作を確認しました。どうやら、最初に思っていたのと違ったようです。
2
+
3
+
4
+
5
+ 問題なく動作するのは**Visual Studioの言語拡張**であり、標準のC++としては**違反**になります。"/W4"で警告レベルを上げると警告が表示され、"/Za"で言語拡張を無効化するとエラーになります。
6
+
7
+ [Temporary Objects Can be Bound to Non-Const References | Microsoft Connect](https://connect.microsoft.com/VisualStudio/feedback/details/807118/temporary-objects-can-be-bound-to-non-const-references)
8
+
9
+ [c++ - Non-const reference bound to temporary, Visual Studio bug? - Stack Overflow](http://stackoverflow.com/questions/16380966/non-const-reference-bound-to-temporary-visual-studio-bug)
10
+
11
+ [c++ - Visual Studio is not creating temporary object when typecasting? - Stack Overflow](http://stackoverflow.com/questions/28402173/visual-studio-is-not-creating-temporary-object-when-typecasting)
12
+
13
+ [コンパイラの警告 (レベル 4) C4239](https://msdn.microsoft.com/ja-jp/library/186yxbac.aspx)
14
+
15
+
16
+
17
+ C++標準ではないVisual Studio特有の仕様ですので、Visual Studioを**永遠に使い続ける**のであれば問題ありません。他のコンパイラでも動作できるように移植する予定であれば、そのような記述は避けるべきでしょう。
18
+
19
+
20
+
21
+ 修正前の下の話は、今回の話ではそうとは言えないので、一般的な話だと思って下さい。
22
+
23
+
24
+
25
+ ---
26
+
27
+ 【修正前】
28
+
1
29
  Clang 700.1.81とGCC 5.3.0ではエラーになってコンパイルできませんね。
2
30
 
3
31
 

2

日本語の修正

2016/02/06 18:22

投稿

raccy
raccy

スコア21735

test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- さて、テンポラリオブジェクトが破棄されると言っても、テンポラリオブジェクトによって使われていたスタック上のメモリ領域が0埋めされるとか、そういうことではありません。スタック上に確保されたメモリ領域は、他に再利用されない限りそのままであり、**無理矢理使用することは可能です**。しかし、言語の仕様上、その領域がいつまでそのままになっているかは一切保証がありません。つまり、**このメモリ領域はもう使う予定は無いから再利用してもいいよ**というのが、**破棄**です。例えば、`base.Show();`の前に何か処理を追加してみて下さい。それだけでテンポラリオブジェクトに使っていたスタック上のメモリ領域が上書きされ、おかしな事が起きる可能性があります。これは、関数が終わった後ローカル変数だけでなく、deleteやfreeでの解放でも同じ事が言えます。
5
+ さて、テンポラリオブジェクトが破棄されると言っても、テンポラリオブジェクトによって使われていたスタック上のメモリ領域が0埋めされるとか、そういうことではありません。スタック上に確保されたメモリ領域は、他に再利用されない限りそのままであり、**無理矢理使用することは可能です**。しかし、言語の仕様上、その領域がいつまでそのままになっているかは一切保証がありません。つまり、**このメモリ領域はもう使う予定は無いから再利用してもいいよ**というのが、**破棄**です。例えば、`base.Show();`の前に何か処理を追加してみて下さい。それだけでテンポラリオブジェクトに使っていたスタック上のメモリ領域が上書きされ、おかしな事が起きる可能性があります。これは、関数が終わった後に破棄されたローカル変数、deleteやfreeでのメモリ解放でも同じ事が言えます。
6
6
 
7
7
 
8
8
 
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- 参考: deletしても使えてしまう例。こっちはClang/GCCでもコンパイルできてしまいます。
13
+ 参考: deleteしても使えてしまう例。こっちはClang/GCCでもコンパイルできてしまいます。
14
14
 
15
15
  ```C++
16
16
 

1

C\+\+\+じゃなくてC\+\+でしょ

2016/02/06 10:46

投稿

raccy
raccy

スコア21735

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  参考: deletしても使えてしまう例。こっちはClang/GCCでもコンパイルできてしまいます。
14
14
 
15
- ```C+++
15
+ ```C++
16
16
 
17
17
  #include <iostream>
18
18