現在C++でMFCプログラミングをしています。
2次元配列のポインタを戻り値とする関数を作成したのですが
プロトタイプ宣言がとても意味不明なことになっています。
おすすめの宣言の仕方があればご教授お願います。
以下ソース一部
static const int HIGH_GRADE_RATE[][2] = {
{ SC_NLANG, 6 },
{ SC_SOCIAL, 4 },
{ SC_MATH, 4 },
}
const int (*CReportChkTblSub::GetOutputRate(void))[2]{
return &HIGH_GRADE_RATE[0];
}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
二次元配列をそのまま返さないとだめなのでしょうか。
GetOutputRateメソッドがどのような使われ方をするのか判らないのですが、こんな感じで作ることは多いです。
C++
1const int* CReportChkTblSub::GetOutputRate(int index) 2{ 3 return &HIGH_GRADE_RATE[index][0]; 4}
あるいは、そもそもデータ構造として二次元配列がふさわしいかどうかを考えるべきです。
初期値化を見る限り、SC_NLANG
と6
が同じ種類の値ではないと思います。おそらく、SC_NLANGのときは6というような使われかたをするのだと思いますが、たとえ両者が同じint型でも区別するべきでしょう。
この場合、構造体を使うのが一般的です。例えば、このような感じで構造体を宣言します。
※構造体名・メンバ変数名は適宜変えてください。
C++
1struct GradeRate 2{ 3 int Grade; 4 int Rate; 5};
そして、HIGH_GRADE_RATE変数はGradeRate構造体の一次元配列で定義します。
C++
1static const GradeRate HIGH_GRADE_RATE[] = { 2 { SC_NLANG, 6 }, 3 { SC_SOCIAL, 4 }, 4 { SC_MATH, 4 }, 5};
一次元配列にしてしまえば簡単に記述できます。
C++
1const GradeRate* CReportChkTblSub::GetOutputRate() 2{ 3 return &HIGH_GRADE_RATE[0]; 4}
最初のコード例にしたがってこういうのも。
C++
1const GradeRate& CReportChkTblSub::GetOutputRate(int index) 2{ 3 return HIGH_GRADE_RATE[index]; 4}
質問の直接的な回答にはなっていないかもしれませんが、より簡単に実装するにはどのようなデータ構造にするかを考えることも重要なことです。場合によっては専用のクラスを作る必要があるかもしれません。C/C++では多次元配列の扱いが非常にややこしいのです。(STLを覚えればまた違ってきますが。)
投稿2015/11/27 12:06
総合スコア5938
0
いやぁ~時間かかりましたよ。
c++
1class CReportChkTblSub { 2 int abc; 3public: 4 int const (*GetOutputRate(void))[2]; 5}; 6 7int const (*CReportChkTblSub::GetOutputRate(void))[2] 8{ 9 this->abc = 0; 10 return HIGH_GRADE_RATE; 11}
検証ソース
c++
1void bbbb() 2{ 3 CReportChkTblSub cc; 4 const int ( *a)[2]; 5 a = cc.GetOutputRate(); 6 const int *p0,*p1,*p2; 7 8 p0 = a[0]; 9 p1 = a[1]; 10 p2 = a[2]; 11 printf("%d\n",p1[1]); 12 printf("%d\n",p2[0]); 13}
お題ありがとうございます。
投稿2015/11/29 01:55
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
考え方はint[2]型へのポインタを返却しているのだと理解しました。
下記のような方法があります。
C++
1// typedef方式 2typedef int ArrayFix2[2]; 3 4const ArrayFix2* GetOutputRate(void) 5{ 6 return &HIGH_GRADE_RATE[0]; 7} 8 9// エイリアス・テンプレート方式 10template<typename tType, std::size_t tSize> 11using Array2D=tType[tSize]; 12 13const Array2D<int, 2>* GetOutputRate2(void) 14{ 15 return &HIGH_GRADE_RATE[0]; 16} 17 18// 使用例 19int main(int argc, char* argv[]) 20{ 21 const ArrayFix2* ArrayPtr = GetOutputRate(); 22 const Array2D<int, 2>* ArrayPtr2 = GetOutputRate2(); 23 return 0; 24}
ArrayFix2はC言語でも可能ですが、型と要素数がint, 2固定です。
Array2DはC++11で導入されたエイリアス・テンプレートを使っています。
型と要素数を指定できます。
でも、int[2]へのポインタを返却するより、struct型へのポインタを返却する方がcatsforepawさんの言う通り分かりやすいと思います。
後、std::vector<>について調べるとより幸せになれるかも知れません。
【閑話休題】
const int (*CReportChkTblSub::GetOutputRate(void))[2]
配列を返却する場合、こんなふうに定義すればできるんですね。
記述できないとばかり思ってました。
C/C++の関数と配列のシグニチャ定義には何時も何時も悩みます。なので、auto様さまです。
投稿2015/11/27 12:44
編集2015/11/27 12:47総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。