アプリ版:「スタンプのみでお礼する」機能のリリースについて

【VC++2005 MFC】構造体のコピーについて

構造体をコピーする時、単純に「=」で代入しているのですが、先輩に
「それじゃコピー出来ないから各メンバごとに代入するような関数作れ」
と言われました。

私自身、C言語の初心者ですが、ネットで調べてみると、単純に「=」で代入出来る
ような気がしております。

ただ拝見したサイトに記載されている構造体は型が「int」「char」なのですが、
「CString」を使っていたり、構造体の中に更に構造体が入っていたりする場合も
単純に「=」で代入出来るのでしょうか?

(というか、実際にコーディング、デバッグして、コピー出来ている事は確認しているん
ですが、先輩いわく、「CStringとかのクラスが含まれている場合はダメだと思う。
メモリが壊れると思う」との事でした。)

A 回答 (3件)

構造体のメンバにポインタ変数がある場合に正しくコピー出来ない場合があります。



strcut Person {
 char *Name;
 int Age;
} Person;

Person Taro,Jiro;
memset(&Taro, 0, sizeof(Person));
memset(&Jiro, 0, sizeof(Person));

Taro.Name = malloc(20);
strcpy(Taro.Name, "太郎");
Taro.Age = 20;

としていた時に、
Jiro = Taro;
でコピーしたから、
free(Taro.Name);
としたら…
Jiro.Name はどうなるでしょう?

この回答への補足

早速のご回答ありがとうございます。

構造体の中にはポインタ変数はひとつも無いです。

上記の場合は・・・
「Jiro.Nameはfreeのタイミングで一緒に解放されてしまう」
で合ってますか?

補足日時:2010/07/12 13:11
    • good
    • 0

明示的にコピー代入演算子を実装しなかった場合,暗黙に定義されるコピー代入演算子は,各メンバ変数に対して


・クラスであれば再帰的にコピー代入演算子を適用
・配列であれば各要素を代入
・スカラ型であればビルトインの代入演算子を適用
となります。
ref) ISO/IEC 14882:2003 (以下IS) 12 Special member functions / 12.8 Copying class objects / paragraph 13
そのため,CStringのメンバ変数があっても,CString::operator=が呼ばれるので問題ないです。

また,コピー代入演算子の明示的な実装を持たないクラスがあった場合でも,それは「暗黙に定義されたコピー代入演算子が存在する」として扱われます。
その結果,メンバ変数は上記の法則によってコピーされます。
# クラスには,構造体や共用体を含みます (IS 9 Classes / paragraph 4)
なお,参照型のメンバ変数やconstメンバ変数があった場合,コピー代入演算子がprivateだった場合などは,暗黙に定義されるコピー代入演算子が存在しないためコンパイル時にエラーになります。
ref) IS 12 / 12.8 / paragraph 12
    • good
    • 0
この回答へのお礼

とても分かりやすく丁寧にご回答いただき、ありがとうございます。
勉強になりますm(__)m

お礼日時:2010/07/12 15:07

>「Jiro.Nameはfreeのタイミングで一緒に解放されてしまう」


>で合ってますか?

合っています。
「一緒に」というのは厳密には違いますが。ポインタは同じものを指していますので。

free()した後でTaro.Name = NULL;
しても、Jiro.NameはNULLにならずに解放済みのメモリを指したままになっています。
アクセスすれば、高確率でアウトでしょう。
# 解放直後なら触れるかも知れませんが、当然正しくない操作になります。


>構造体の中にはポインタ変数はひとつも無いです。

構造体メンバにクラスが入っていて、その中で…ということもあり得ますので、注意が必要である点には変わりない…かと。
「これから先、構造体のメンバが追加された時にポインタ変数が追加されるかも知れないから…」
ということかも知れませんし。

#2さんが書かれている通り、クラスに対してコピーコンストラクタが正しく実装されていれば大丈夫かと思われます。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございますm(__)m
とても勉強になります。
今回の構造体には入れ子になっている構造体含めてポインタは存在しないため、
単純な代入処理のままにしておこうと思います。

お礼日時:2010/07/12 15:09

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!