を作る私の状況です:私はconst参照メンバ変数を持つクラスを持っているC++ 11でクラス基準部材の初期化は、ここで悪いコピー
- 。
- 私はそのメンバ変数をconst参照から初期化しようとしています。
私の問題は、メンバ変数がクラス内で初期化されると、問題のオブジェクトの一時的なコピーが作成され、一時的なアドレスが参照に使用されるということです。メンバ変数がコンストラクタ初期化子リストで初期化されると、コピーは作成されません。どちらの方法でも、プログラムは、g ++ 4.8.3でC++ 11またはC++ 1yのいずれかのフラグを使用して警告なしで正常にコンパイルされます。
以下は、最小限のプログラムと出力です。私はちょうどそれがなぜ起こるか(またはそれがバグであるかどうか)知っているので、このよりよいルールを理解したいと思うでしょう。
#include <iostream>
using namespace std;
struct A
{
A()
{
cout << "creating an A at " << this << endl;
}
A(const A & a)
{
cout << "copying an A from instance at " << & a << " to instance at " << this << endl;
}
};
A g_aardvark;
const A & GetAardvark()
{
cout << "returning an A at " << & g_aardvark << endl;
return g_aardvark;
}
struct B
{
B()
: m_a1(GetAardvark())
, m_a2(g_aardvark)
{ }
const A & m_a1;
const A & m_a2;
const A & m_a3{ GetAardvark() };
const A & m_a4{ g_aardvark };
};
int main()
{
B butter;
cout << "B has m_a1 at " << & butter.m_a1 << endl;
cout << "B has m_a2 at " << & butter.m_a2 << endl;
cout << "B has m_a3 at " << & butter.m_a3 << endl;
cout << "B has m_a4 at " << & butter.m_a4 << endl;
return 0;
}
サンプル出力:
creating an A at 0x601494
returning an A at 0x601494
returning an A at 0x601494
copying an A from instance at 0x601494 to instance at 0x7fffc595f87f
copying an A from instance at 0x601494 to instance at 0x7fffc595f87e
B has m_a1 at 0x601494
B has m_a2 at 0x601494
B has m_a3 at 0x7fffc595f87f
B has m_a4 at 0x7fffc595f87e
メモリが役立つ場合、これはgccのリスト初期化のバグで、4.9で修正されています。はるかに単純なコードで再現できるはずです。 'int main(){A a; const&b {a}; } ' –
どのコンパイラのバージョンを使用していますか?このコードにはコピーはありません:http://coliru.stacked-crooked.com/a/f30df5ef62b45420 –