String型を含む構造体のメンバを簡単に初期化するには? – プログラミング – Home

String型を含む構造体のメンバを簡...
 
通知
すべてクリア

[解決済] String型を含む構造体のメンバを簡単に初期化するには?


まに
 まに
(@まに)
ゲスト
結合: 18年前
投稿: 78
Topic starter  

お世話になります。
整数型とString型が混在する構造体の各メンバを、
初期化(整数型は0で、String型は"で)したいのですが、
簡単な方法はないものでしょうか?

下記のプログラムのようにmemsetで一度に初期化すると、
実行時エラーが発生してしまいます。
やはり、各メンバを一つ一つ初期化していくしかないのでしょうか?

struct DataTable {
short a1;
short a2;
short a3;
short a4;
CString s1;
};

void Run(void)
{
DataTable A;
memset(&A, 0, sizeof(A));
A.s1 = AHO; // ここで実行時エラーが発生
}

環境は、WinXP Home、VC++2005です。


引用未解決
トピックタグ
RAPT
 RAPT
(@RAPT)
ゲスト
結合: 22年前
投稿: 310
 

初期化を行なうのであれば、まさにコンストラクタの仕事です。

struct DataTable {
short a1;
short a2;
short a3;
short a4;
CString s1;

DataTable() : a1( 0 ), a2( 0 ), a3( 0 ), a4( 0 )
{
}
};


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

CStringをmemsetで0に書き換えれば管理情報が吹っ飛びますから、
落ちて当然でしょう。
クラスをmemsetで0に埋めるのはC++では初期化とは言いません。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

String型とCString型は別ものだと思いますが。
(はっきり書かないといけないところ)
# VC++でString型となると、.NET FrameworkのSystem::Stringクラスに
# string型と、先頭一文字が小文字であれば、STLのstd::stringクラスに思われる。
# 同様なところで、Char型(.NET FrameworkのSystem::Char型)とchar型はまったく違
う。

類似スレです。

構造体のメンバにCStringを使用する方法
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200612/06120056.txt


返信引用
まに
 まに
(@まに)
ゲスト
結合: 18年前
投稿: 78
Topic starter  

RAPTさん、Banさん、Blueさん、ありがとうございます。

自己レスですが、
「memset(&A, 0, sizeof(A)-sizeof(CString));」
とやれば整数型だけを初期化できるということを思いつきました。

しかし、安全なコードとは言えないし、実際には
CString型(String型じゃなかったですね、すみません)
のメンバが構造体の真ん中付近に定義されているので、
やっぱり各メンバを一つ一つ初期化したほうがいいように思えてきました。

整数型もCString型も一括で初期化してくれるような命令が、
もしあればいいな~と思い、書き込んでみたのですが、
冷静に考えて、そんな都合のいい命令があるわけないですよね。
失礼しました。


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

> 整数型もCString型も一括で初期化してくれるような命令が、

これをやらせるのが、コンストラクタでの初期化なのですが。
(RAPTさん指摘済み)

使う側は毎回書かなくても、勝手に初期化してくれるのですよ>コンストラクタ
とはいえ「どういう初期化をするか」の指定はどこかに必要。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

つまり、やりたいことって

構造体の定義は変更できない。
コンストラクタの追加やメンバ変数の並びの変更等一切できない。

という前提条件で、いかに効率よくCStringのメンバ変数以外を
初期化させるか?

でしょうか?

多分スマートな方法はないでしょう。
>「memset(&A, 0, sizeof(A)-sizeof(CString));」
この方法は、常に構造体のオフセットに依存するし、
私はPODな構造体に対してmemsetをつかうってことは気持ち悪くてできないなぁ。

やはり
>各メンバを一つ一つ初期化
がいちばんベストでしょうね。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

間違えました。

>私はPODな構造体に対して
PODでない構造体に対して

です。
PODな構造体なら、

Hoge h = {0};

というふうに初期化できると思います。


返信引用
まに
 まに
(@まに)
ゲスト
結合: 18年前
投稿: 78
Topic starter  

> つまり、やりたいことって
>
> 構造体の定義は変更できない。
> コンストラクタの追加やメンバ変数の並びの変更等一切できない。
>
> という前提条件で、いかに効率よくCStringの
> メンバ変数以外を初期化させるか?
>
> でしょうか?

はい、その通りです。
なにしろ、メンバが30個以上もあるので、
一つ一つ初期化するより、memsetかなにかで
まとめて初期化できないか?と思い、書き込みさせていただきました。
そうすれば、1~2行で済みますし。

コンストラクタについても(よく理解してませんが)、
「a1( 0 ), a2( 0 ), a3( 0 ), a4( 0 )…」と一つ一つ
初期化しないとならない点は変わらないと思います。
それに、この構造体を使っているところは何箇所かあるのですが、
初期化したいのはそのうちの1箇所だけなんです。
なのでコンストラクタにするメリットもあまり感じられないかと…。

やはり、メンバを一つ一つ初期化します。
どうもありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました