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

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

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

Re[6]: C++の構造体コンストラクタ


(過去ログ 70 を表示中)

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

■41048 / inTopicNo.1)  C++の構造体コンストラクタ
  
□投稿者/ ふくちゃん (61回)-(2009/09/10(Thu) 16:13:49)

分類:[C/C++] 

2009/09/10(Thu) 16:14:52 編集(投稿者)
C++の構造体のコンストラクタについて質問です。

下のコードはコンパイルが通ります。

	struct Tbl{
		int type;
		int valTbl[10];
	};

	static const Tbl tbl[] = {
		{1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
		{2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
		{3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
	};


ただ、C++のなるべく初期化しましょうという原則に従い、
悔い改めて、構造体にデフォルトコンストラクタを追加すると
初期化リストの引数の数が違うというコンパイルエラーが
出ます。

	struct Tbl{
		int type;
		int valTbl[10];

		/** デフォルトコンストラクタ */
		Tbl() : type(0) {
			memset(valTbl, 0, sizeof(int)*_ARRAYSIZE(valTbl));
		}
	};

	static const Tbl tbl[] = {
		{1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
		{2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
		{3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
	};


こんな場合、どういう風に対処しますか?
教えてください。

引用返信 編集キー/
■41050 / inTopicNo.2)  Re[1]: C++の構造体コンストラクタ
□投稿者/ 774RR (387回)-(2009/09/10(Thu) 16:40:17)
結局のところ「最終的にどうしたいのか?」次第なところがあるわけで・・・

単に定数テーブルが欲しいだけなら、そもそもこのクラスにコンストラクタを設けるのが間違い。
最初の struct Tbl のほうが実装として素直だと思われる。
俺なら最初のコードのままとすると思う ( {} のつけ方は変えると思うが )

プロジェクトの規約として、なんとしてでもコンストラクタが絶対に必須とか
欲しいのは定数テーブルではなくって・・・とか
そういうことならその旨書いて欲しい。

引用返信 編集キー/
■41051 / inTopicNo.3)  Re[2]: C++の構造体コンストラクタ
□投稿者/ ふくちゃん (62回)-(2009/09/10(Thu) 17:17:59)
No41050 (774RR さん) に返信
> 結局のところ「最終的にどうしたいのか?」次第なところがあるわけで・・・
>
> 単に定数テーブルが欲しいだけなら、そもそもこのクラスにコンストラクタを設けるのが間違い。
> 最初の struct Tbl のほうが実装として素直だと思われる。
> 俺なら最初のコードのままとすると思う ( {} のつけ方は変えると思うが )
>
> プロジェクトの規約として、なんとしてでもコンストラクタが絶対に必須とか
> 欲しいのは定数テーブルではなくって・・・とか
> そういうことならその旨書いて欲しい。
>

基本的には前者で私もコーディングしていたのですが、
このたび Effective C++ の本を読み、なるべくコンストラクタを付けましょうということを
学びました。

ですので、デフォルトコンストラクタをまじめに書いてみるとコンパイルエラーになった次第です。

> プロジェクトの規約として、なんとしてでもコンストラクタが絶対に必須とか
> 欲しいのは定数テーブルではなくって・・・とか
> そういうことならその旨書いて欲しい。

にお答えしますと、 Effective C++  の本をコーディング規約とするのならば
デフォルトコンストラクタはつけたいところですね。

引用返信 編集キー/
■41052 / inTopicNo.4)  Re[3]: C++の構造体コンストラクタ
□投稿者/ επιστημη (2160回)-(2009/09/10(Thu) 17:20:24)
επιστημη さんの Web サイト
やるならこんな感じかしら。

#include <cstddef>
#include <cstdarg>
#include <numeric>
#include <iostream>
#include <iterator>
#include <algorithm>

struct Tbl{
  static const int N = 10;
  int type;
  int valTbl[N];

  Tbl() : type(0) { std::fill_n(valTbl, N, 0); }
  Tbl(int t) : type(t) { std::fill_n(valTbl, N, 0); }
  Tbl(int t,...) : type(t) {
    va_list argptr;
    va_start(argptr, t);
    for ( int i = 0; i < N; ++i ) {
      valTbl[i] = va_arg(argptr,int);
    }
  }
};

std::ostream& operator<<(std::ostream& stream, const Tbl& tbl) {
  stream << "type: " << tbl.type << "\t : ";
  std::copy(tbl.valTbl, tbl.valTbl+Tbl::N, std::ostream_iterator<int>(stream," "));
  return stream << std::endl;
}

int main() {
  static const Tbl tbl[] = {
    Tbl(1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
    Tbl(2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0),
    Tbl(3, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1),
  };
  std::copy(tbl, tbl+3, std::ostream_iterator<Tbl>(std::cout,""));
}

引用返信 編集キー/
■41056 / inTopicNo.5)  Re[4]: C++の構造体コンストラクタ
□投稿者/ 774RR (388回)-(2009/09/10(Thu) 18:25:07)
俺は組み込み系がメインだから
そこまでしてコンストラクタにこだわって各種コスト高にするくらいなら
最初のコードを採用するだろうな・・・
・たかが const int なのに実行時コピーが必要なの?
・しかも stdarg で可変個引数機能まで必要とするわけ?
・そもそも static const なテーブルだけなら希少な RAM を使いたくないなー
などと考えてしまうわけだ。

C/C++ は極限に突っ走ることも中庸を重んじることもできる言語なわけで
・コンストラクタがない struct は使用禁止、と極限を追求してもいいし
 (C との互換性を捨ててでも理想にこだわる)
 (実行時効率を捨ててソースコードの理想形の極限を追求)
・C と互換な POD 型に留めておくという中庸にとどまってもいいし
 (実行時効率とソースコードの表記上の理想と、バランスさせる)
プログラマのさじ加減ひとつでなんとでもなる。
引用返信 編集キー/
■41059 / inTopicNo.6)  Re[5]: C++の構造体コンストラクタ
□投稿者/ ふくちゃん (63回)-(2009/09/10(Thu) 19:01:47)
επιστημη さんすごい!!
もし書くとしたらという問いに答えていただきありがとう!!!!
コンストラクタでやるとこうだ!という例がほしかったんです。^^

コードを見る限り、ここまでする意味は確かになさそうですね。

みなさんのおっしゃる通り、
結局のところ、用途に合わせてってところに行きつくんですかね。

了解いたしました。


ちなみに下のようなコードって、いったいどんな風な
方法できちんとデータが入っているんでしょうか?
バイト数が違うCString型でもちゃんと値が入りますよね?

	struct Tbl{
		int type;
		CString typeName;
		int ans;
		CString ansName;
	};

	static const Tbl tbl[] = {
		{1, "国語", 80, "合格"},
		{2, "国語(漢字)", 90, "合格"},
		{3, "数学", 70, "不合格"},
	};

これがうまく動作する理由はコンパイラが下のような
コンストラクタを作ってくれているからでしょうか?

  Tbl(...)  {
    va_list argptr;
    va_start(argptr, t);
    type = va_arg(argptr,int);
    typeName= va_arg(argptr,CString);
    ans= va_arg(argptr,int);
    ansName= va_arg(argptr,CString);

  }


引用返信 編集キー/
■41061 / inTopicNo.7)  Re[6]: C++の構造体コンストラクタ
□投稿者/ επιστημη (2161回)-(2009/09/10(Thu) 21:37:17)
επιστημη さんの Web サイト
> これがうまく動作する理由はコンパイラが下のような
> コンストラクタを作ってくれているからでしょうか?

いや、メンバごとにコンストラクタを起動しているだけでしょう。

tbl[0].type(1);
tbl[0].typeName("国語");
tbl[0].ans(80);
tbl[0].ansName("合格");

みたいな。

引用返信 編集キー/
■41062 / inTopicNo.8)  Re[7]: C++の構造体コンストラクタ
□投稿者/ ふくちゃん (64回)-(2009/09/10(Thu) 21:47:39)
なるほど。

でしたら納得できました。
構造体の変数をconstにしてもうまくいっていたので、
どんな感じなのかなと疑問に思っておりましたので^^;

ありがとうございます^^

No41061 (επιστημη さん) に返信
>>これがうまく動作する理由はコンパイラが下のような
>>コンストラクタを作ってくれているからでしょうか?
>
> いや、メンバごとにコンストラクタを起動しているだけでしょう。
>
> tbl[0].type(1);
> tbl[0].typeName("国語");
> tbl[0].ans(80);
> tbl[0].ansName("合格");
>
> みたいな。
>
解決済み
引用返信 編集キー/
■41064 / inTopicNo.9)  Re[6]: C++の構造体コンストラクタ
□投稿者/ επιστημη (2162回)-(2009/09/11(Fri) 01:49:58)
επιστημη さんの Web サイト
> もし書くとしたらという問いに答えていただきありがとう!!!!
> コンストラクタでやるとこうだ!という例がほしかったんです。^^

んー...でもねー、可変長引数使っちまったから引数の型/数についてノーチェックなのねー
なのでオススメはしかねます。

引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -