トップページ⇒tech
1001コメント319KB

C++相談室 part41

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2005/07/01(金) 13:09:21
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
テンプレートライブラリ(STL含む)に関する質問は
専用の別スレにお願いします。
IDE(VC++など)などの使い方の質問もその開発環境のスレに
お願いします。

前スレ part40
http://pc8.2ch.net/test/read.cgi/tech/1113408957/

過去スレ、関連スレ、関連リンクなどは >>2-20 あたり
0685デフォルトの名無しさん2005/08/04(木) 13:17:02
>>684
ダライアス継承は仮想継承にしてなんぼだろうが。
0686デフォルトの名無しさん2005/08/04(木) 15:23:14
>>685
あとは たのむ
0687デフォルトの名無しさん2005/08/04(木) 19:49:35
>>684
A::~A() が virtual になっているなら空の B::~B() を手動で定義しなくてよい
0688デフォルトの名無しさん2005/08/04(木) 22:32:20
>>687
そうなのか?てっきり全部ばらばらの働きをするデストラクタも含めて継承して
この例だとIか、あの最後の奴を継承したときどうなるかってことだと思ってたんだが。
685とあわせて全然修行不足だな。すまん。
0689デフォルトの名無しさん 2005/08/04(木) 22:56:17
動的に確保して値を代入した5次元の配列2つをあるクラスに渡すには
どうすれば?
int a[s][t][u][v][w]
int b[s][t][u][v][w]
という配列に値は入っています。
クラス (ここをどうするか)
{コンストラクタで代入はできますか}
0690デフォルトの名無しさん2005/08/04(木) 23:02:19
unko::unko((int (*manko)[s][t][u][v])) : chinko(manko) { }
0691デフォルトの名無しさん2005/08/04(木) 23:20:30
TEST::TEST(int (*kontena)[s][t][u][v])) :kontena2( kontena)
{
}
よくわかりません。解説お願いします。
これでa,b2つの配列ともクラスに渡せて、そのクラスの中で配列に入っている値を得ることが
できますか?
TEST::TEST(int 何か,int 何か){}のようなものを予想していました。
0692デフォルトの名無しさん2005/08/04(木) 23:22:24
>>691
次元を減らして考えてみろ。
0693デフォルトの名無しさん2005/08/04(木) 23:25:25
TEST::TEST(int a1[][t][u][v][w],int a2[][t][u][v][w])
{}
こういうことでしょうか?
0694デフォルトの名無しさん2005/08/04(木) 23:28:12
ありゃりゃ、括弧が2重になってるやん
あーあ俺もいいかげん焼き回ったな
0695デフォルトの名無しさん2005/08/04(木) 23:29:48
>>693
そう思ったら、聞く前にまず試してみる
0696デフォルトの名無しさん2005/08/04(木) 23:32:03
だめみたいです。
内部で新たに5次元配列を宣言して渡すという形にしたほうがいい?
動的配列だからその方法もわかりません。
0697デフォルトの名無しさん2005/08/04(木) 23:38:53
>>696
何がどうダメだったのか、分かるか?
0698デフォルトの名無しさん2005/08/04(木) 23:43:19
配列が渡ってないようです。
TEST::TEST(int a1[][t][u][v][w],int a2[][t][u][v][w])
{ここになにか}
そりゃ入れないとだめですね。

3次元動的配列をクラスに渡す場合はどうやるのでしょうか?それを応用して考えてみようを思います。
配列の渡しわからねーー。
0699デフォルトの名無しさん2005/08/04(木) 23:49:05
n次元動的配列って(1次元になるまで多重に)ループで
ひとつ低い次元の配列を要素サイズ分確保してループで埋めて作るやつかね?
そんなの自動で渡る方法なんかないっしょ。
クラス作ってコピーコンストラクタも提供でもせんと
0700デフォルトの名無しさん2005/08/04(木) 23:51:08
>>699
そうです。自動で渡る方法ないんですか?
0701デフォルトの名無しさん2005/08/05(金) 00:08:20
動的に確保したんだろ?
TEST::TEST(int***** a1,int***** a2)
これじゃまずいか
0702デフォルトの名無しさん2005/08/05(金) 00:14:33
その方法わかるんやけど、どうやって配列の値を受け取るかわかる?
こんな風にクラスのある内部関数で
int temp =a1[2][2][4][5][7];
0703デフォルトの名無しさん2005/08/05(金) 00:30:31
TEST::TEST(int***** a1,int***** a2,int s, int t, int u, int v, int w)

妥協
0704デフォルトの名無しさん2005/08/05(金) 01:16:34
つかvector使えば?
0705デフォルトの名無しさん2005/08/05(金) 01:31:13
>>689
コンストラクタで組み込み配列型メンバの初期化は制御できない。全部デフォルトの初期化になる。
つまり無理。
0706デフォルトの名無しさん2005/08/05(金) 04:07:11
>>691
配列を渡したいのか、配列へのポインタを渡すだけで良いのかによって変わる。
2次元で考えると:

class X {
int **_x, **_y;
public:
X(int **x, int **y) : _x(x), _y(y) {}
};

自分なら、配列や配列へのポインタは扱わず、多次元配列のクラスを使う。
既存品ならBoost.Multiarrayかな。
でも5次元に特化した配列クラスなら1時間もあれば書けるでしょ。
そのクラスのインスタンスを、受け取りたい関数に渡す。

void f(CMultiArray *X, CMultiArray *Y) {}
CMultiArray *A = new CMultiArray(s, t, u, v, w);
CMultiArray *B = new CMultiArray(s, t, u, v, w);
f(A, B);

または、その5次元配列がなんらかの処理とセットで使われるなら、
それらをまとめてひとつのクラスにする。

ハッキリ言って5次元配列とかnewのループまわして作るのめんどいので
配列自体をカプセル化した方が良いよ。
0707デフォルトの名無しさん2005/08/05(金) 10:37:28
コンストラクタ初期化子で
基底クラスの初期化の前に
派生クラスのオブジェクトを初期化することはできないのでしょうか?
0708デフォルトの名無しさん2005/08/05(金) 10:39:24
無理。設計を見直しましょう。
0709デフォルトの名無しさん2005/08/05(金) 10:40:50
>>707
boost::base_from_memberを使えばできる。
http://www.kmonos.net/alang/boost/classes/base_from_member.html
07107072005/08/05(金) 11:19:39
>>708,709
ありがとうございます。
先に派生クラスのメンバを持つクラスを継承しておけば初期化できるんですね。

0711デフォルトの名無しさん2005/08/05(金) 12:51:35
>>707
そもそも、派生クラスのオブジェクトに依存する基底クラスって設計がおかしい気がするのだが……
0712デフォルトの名無しさん2005/08/05(金) 13:39:57
doxygenより楽にドキュメント作る方法ないんでしょうか?
Visual Studioに便利がツールが添付されてたりとか・・・
0713デフォルトの名無しさん2005/08/05(金) 13:42:26
class Base {
  Base(){
    ((Ext*)this)->init();
    this->i = 0;
  }
};
class Ext {
    init();
};
これでひとつ。
0714デフォルトの名無しさん2005/08/05(金) 17:05:24
>>712
VBCommenter 参考にしてプラグインを”自作”。
ただし C++ 用の CodeDOM は実装されていないので、
気合でパーサ書いて、実装しないとダメかも。
0715デフォルトの名無しさん2005/08/06(土) 00:52:20
C++でsetjmp(),longjmp()を使ったら例外処理とか
まともに動く保証は無い?
0716デフォルトの名無しさん2005/08/06(土) 01:05:05
18.7.4 の意味を正確に掴め兼ねるが多分、意訳すると
「catch 句の中へ飛ぶような使い方はするなボケ」で、
それ以外は規格的には大丈夫っぽい。

解釈が間違ってたら誰かふぉろーよろしく。
0717デフォルトの名無しさん2005/08/06(土) 01:38:38
まぁ、基本的にはC++でsetjmp/longjmp使うぐらいなら例外で処理しとけ。
0718デフォルトの名無しさん2005/08/06(土) 07:50:32
>>715-716
同じ流れを例外で行えばデストラクタが呼ばれるとき、longjmpを行うと未定義と書いてある。
JIS X3014 18.7
0719デフォルトの名無しさん2005/08/06(土) 12:50:25
>>718
あー、"解体"ってのがデストラクタのことか。
俺も JIS X3014 を見てたんだけど、
ISO/IEC 14882 のほうがやっぱり読みやすいね。
0720デフォルトの名無しさん2005/08/06(土) 15:37:27
随伴って何のことかと思ったよ
0721デフォルトの名無しさん2005/08/06(土) 16:53:54
外部ファイルから読み取った値で,クラスのstatic const メンバー変数を初期化したいのです。
たくさんの(50くらいの)メンバーをこの方法で初期化するため,ファイルを読み込むクラスも作りました。⇒LoadFile
この方法ではうまく初期化できなかったので,別の方針をお尋ねしたいのですが…。
一度mapに全部ファイルの内容を流し込んでしまう方法も考えましたが,流し込む時点ではメンバーの型が
分からないので困っています。(外部ファイルに例えば「L=3」と書いてあっても,mapに追加する時点では
int, double, charのどれに利用するのか分からない)


#include <iostream>
#include "LoadFile.h"
using namespace std;

class Hoge {
   static const int L;
   static const double X;
public:
   int getL() const { return L; }
   double getM() const { return X; }
};

LoadFile fl("test.dat");   //ファイル名を渡すとそこから読み込んでくれるようにしました
/*fl.func();*/   //メソッドはいじれない
const int Hoge::L = 2;
/*const int Hoge::M = fl.getDouble("X");*/   //メソッドはいじれない

int main() {
   Hoge hoge;
   cout << hoge.getL() << endl;
/*  cout << hoge.getX() << endl;*/
   return 0;
}
0722デフォルトの名無しさん2005/08/06(土) 16:58:38
実行時に動的に初期化することはできません。
0723デフォルトの名無しさん2005/08/06(土) 17:07:05
>>721
なんで static const になってんの?
Hoge のインターフェースを見ると、メンバに LoadFile 持てばいいだけに見えるけど。
0724デフォルトの名無しさん2005/08/06(土) 17:09:01
class について質問です。

class A {.....};

int main() { A a[20160]; }

とするとエラーが出ます。
自分で定義したクラスの配列には、制限があるのでしょうか。お願いします。
0725デフォルトの名無しさん2005/08/06(土) 17:10:03
>>724 エラーが出るならエラーメッセージ貼れ。
0726デフォルトの名無しさん2005/08/06(土) 17:11:48
デフォルトコンストラクタがないと予想
07277242005/08/06(土) 17:16:30
SIGSEGV です。メモリのアクセス違反でしょうか。
取りあえずコンストラクタ作ってみます。リアルタイムでサンクス。
0728デフォルトの名無しさん2005/08/06(土) 17:18:55
int main(){
  char c[4ギガ]
}
0729?V?Q?S2005/08/06(土) 17:30:50
class A のサイズ576ですた(泣。
07307212005/08/06(土) 17:43:17
お二方,どうもありがとうございます。

>>722
そうですか…orz

>>723
staticなのは,Hogeのオブジェクト(複数)間で共通の定数だからですが,
定数なのでconstをつけようとして,おかしくなってきました。
もともとメンバーにLoadFileがあったので,staticだけにする方向で行きます。
0731デフォルトの名無しさん2005/08/06(土) 21:35:36
他の関数からは見えないけどサブルーチンからだけは見える変数って作れる?

関数{
  変数宣言
  サブルーチン呼び出し
}

サブルーチン{
  呼び出し元の変数使用
}

みたいに
0732デフォルトの名無しさん2005/08/06(土) 21:46:08
またきた・・・
0733デフォルトの名無しさん2005/08/06(土) 21:46:13
>>731
無理。
そういうのはインタプリタ言語じゃないと難しいと思う。
0734デフォルトの名無しさん2005/08/06(土) 21:49:28
>>731
サブルーチン内のstatic変数とかじゃダメなん?
0735デフォルトの名無しさん2005/08/06(土) 21:55:21
サブルーチンって懐かしい言葉だな
0736デフォルトの名無しさん2005/08/06(土) 22:00:16
>>731 関数とサブルーチンの違いは何なの?
0737デフォルトの名無しさん2005/08/06(土) 22:01:41
つか引数でわたしゃいいんじゃねーの?
0738デフォルトの名無しさん2005/08/06(土) 22:06:51
まず考えるのは引数で参照(or ポインタ)渡しじゃないの?
0739デフォルトの名無しさん2005/08/06(土) 22:19:07
スタックさかのぼるとか
「サブルーチンからだけは見える」は実現できないけど
0740デフォルトの名無しさん2005/08/06(土) 22:32:22
>>731
擬似的に
void func() {
    struct {
        int internal;
        void routine() {
            hoge(internal);
        }
    } sub;
    sub.routine();
}
0741デフォルトの名無しさん2005/08/06(土) 22:55:13
>>733-740
マルチすまん
なんか難しそうなことはわかった
素直に参照渡し使うことにする
0742デフォルトの名無しさん2005/08/07(日) 05:13:56
struct A
{
  A* hello()
  {
    std;;cout _<< "Hello" << std::endl;
  }
  A* operator->()
  {
    std::cout << "A::oprator->()" << std::endl;
    return this;
  }
  A* operator[](const std::string& s)
  {
    std::cout << "A::operator[]()" << std::endl;
    return this;
  }
  A* operator()()
  {
    std::cout << "A::operator()()" << std::endl;
    return this;
  }
};
int main()
{
  A a;
  a->hello()   //OK
  a->();       //error
  a->["hello"];  //error
}
operator->でA*を返してるはずなのにエラーになったりならなかったり
どういうことでしょうか? vc7.1です
0743デフォルトの名無しさん2005/08/07(日) 05:31:12
>>742
a.operator->();
a.operator()();
0744デフォルトの名無しさん2005/08/07(日) 05:34:56
>>742
なんでコピペしないで手で写してるの?
0745デフォルトの名無しさん2005/08/07(日) 09:17:25
>>742
operator []()は普通参照を返すけど。
0746デフォルトの名無しさん2005/08/07(日) 11:22:49
なんでこう的外れなレスばっか出てくるんだろう。
0747デフォルトの名無しさん2005/08/07(日) 11:45:24
夏休みだから。
0748デフォルトの名無しさん2005/08/07(日) 11:51:08
>>742
->の後にはメンバがなければならない。
[]や()はたとえオーバーロードしていようと演算子だから->の後には続けられない。
0749デフォルトの名無しさん2005/08/07(日) 12:17:37
>>748
"operator"も書けば呼べなくもない
0750デフォルトの名無しさん2005/08/07(日) 13:37:16
a->operator[]("hello");
0751デフォルトの名無しさん2005/08/07(日) 14:17:44
かなり初歩的な質問ですいませんが教えてください。
特別バージョンに指定するtemplate<>ですが、どうしてこれを書く必要があるのかわかりません。

template<typename T>
class C {
  // ...
};

//template<>
class C<int> {
  // ...
};

下が上の特別バージョンであることをコンパイラは判断できないんですか?
0752デフォルトの名無しさん2005/08/07(日) 15:07:07
>>751 回答じゃなくて悪いが、なんでこれが初歩的な質問だと思ったんだ?
0753デフォルトの名無しさん2005/08/07(日) 15:12:40
>>751
下の書き方じゃ変数化したいintと普通のintの区別が付かないから
0754デフォルトの名無しさん2005/08/07(日) 15:14:13
>>751
明示的インスタンス化の宣言が template class C<int>; だから、
class C<int>; だけの場合を許すとして、
明示的インスタンス化と見るか明示的特殊化と見るかを決めかねるんじゃないか?
0755デフォルトの名無しさん2005/08/07(日) 16:05:20
>>752
なにぶんテンプレート初心者なもので。

>>753
テンプレート引数なのか型名なのか区別が付かないということでしょうか??

>>754
定義も一緒にする場合にはtemplate<>は付けなくてもいいということですか?
template<typename T> class C
{
public:
  void f() {
    printf("C<T>::f\n");
  }
};
//template<>
class C<int> {
public:
  void f() {
   printf("C<int>::f\n");
  }
};
void main() {
  C<float> c1;
  c1.f();
  C<int> c2;
  c2.f();
}
とりあえず上のプログラムをVSN2002でコンパイルしたら下のような出力になりました。
C<T>::f
C<int>::f
07567542005/08/07(日) 16:22:49
>>755
伝わらなかったみたいだな。ごめんよ。

class C<int>; を許すとして、
template class C<int>; と見るか、
template<> class C<int>; と見るか、
どっちにするか決められないんじゃないか、ってこと。
0757デフォルトの名無しさん2005/08/07(日) 16:23:55
C++知らないんだけど、その二つはどうちがうの?
0758デフォルトの名無しさん2005/08/07(日) 16:24:54
>>757
C++知らないのにどうしてここを見ているの?
07597542005/08/07(日) 16:30:01
あれ?
gcc 3.4.4 でも MSC でも class C<int>; が
明示的特殊化の宣言( template<> class C<int>; )として通った。
こんなの規格にあったっけ?
07607542005/08/07(日) 16:37:14
定義も加えようとする( class C<int> {}; )と、エラーになる。

gcc 3.4.4:
error: an explicit specialization must be preceded by 'template <>'

vctoolkit2003:
error C2906: 'C<int>' : explicit specialization requires 'template <>'

どちらも明示的特殊化として認識はできているが、
文法としては template<> が必要だからしょうがなくエラーって感じだな。
0761デフォルトの名無しさん2005/08/07(日) 16:47:57
とりあえずtemplate<>は付けておかないとダメそうということはわかりました。
これは言語の仕様として必ず必要ということになってるんでしょうか?
それともコンパイラに依存するとなっているんでしょうか?
0762デフォルトの名無しさん2005/08/07(日) 16:54:16
>>761 http://www.kuzbass.ru/docs/isocpp/template.html#temp.expl.spec
0763デフォルトの名無しさん2005/08/07(日) 17:02:47
>>762
言語仕様として必要なんですね。
それだけわかれば良かったんです。
コンパイラの話にしてしまってすいません。
ありがとうございました。
0764デフォルトの名無しさん2005/08/08(月) 00:49:46
>759
class C<int> なら構文的には forward declaration として認識されるような気がする。
規格書ちゃらっと見てみた限りでは friend 宣言で使われてたよーな。
0765デフォルトの名無しさん2005/08/08(月) 00:55:33
>764 補足
セミコロンが抜けた。 class C<int>; ね。
で、friend class task<int>; って記述があったってことね。
0766デフォルトの名無しさん2005/08/08(月) 01:07:45
>>764-765
構文として forward declaration などというものは存在しないわけで、何が言いたいのかわからん。
0767デフォルトの名無しさん2005/08/08(月) 03:13:16
C++で使えるコルーチンライブラリってある?
0768デフォルトの名無しさん2005/08/08(月) 06:03:49
>>767 Win32API Fiber Functions
0769デフォルトの名無しさん2005/08/08(月) 21:50:52
>766
構文としては explicit-specialization じゃなくて単なる declaration であり、
解釈としては forward declaration として見なされるのではないか?ということです。
0770デフォルトの名無しさん2005/08/08(月) 23:07:16
>>769
ISO/IEC 14882:2003にない造語で勝手に語らないでくれないか。
0771デフォルトの名無しさん2005/08/08(月) 23:11:09
>>770
オマエモナー
0772デフォルトの名無しさん2005/08/08(月) 23:26:31
>>771
???
0773デフォルトの名無しさん2005/08/08(月) 23:32:51
you too
0774デフォルトの名無しさん2005/08/08(月) 23:59:27
>>771
「オマエモナー」の使い方がおかしい。
0775デフォルトの名無しさん2005/08/09(火) 02:01:36
>>769
ちょっと >759 を読み直してみろよ。

構文としては simple-declaration であるはずの class C<int>; が
explicit-specialization と同様に扱われているようだが、
そう扱うように規格で定められているのか?というのが問題なわけよ。

「forward declaration として見なされるのではないか?」なんてのは的外れ。
そもそも「forward declaration」という言葉の意味が
規格中で定義されていないので、この流れの中では意味不明。
0776デフォルトの名無しさん2005/08/09(火) 03:34:32
>775
ごめん。
確かに的はずれで、explicit-specialization 「の宣言」 (14.7.3/2) が俺脳内 forward declaration そのものでした。

forward declaration については 9.1/2 で言及があるんですが、class-key identifier の場合なので template-id
である今回の場合はあてはまらない。
7.1.5.3 の elaborated type specifier で、かつ単一の構成要素なので 7.1.5.3/1 の場合だと思うんですが、
そうすると friend ついてないし、結局 explicit specialization か explicit instantiation じゃないとだめ。
でも template も template <> もついてないから、そっちもだめ。

この辺は friend class C<int>; を認めるために 14882:1998 から変更されてるみたいですが、
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#68
規格上は class C<int>; は ill-formed だというのが正しいんじゃないでしょうか?
0777デフォルトの名無しさん2005/08/09(火) 04:35:30
コンストラクタ初期化子で
配列を初期化するのは可能なのでしょうか?
0778デフォルトの名無しさん2005/08/09(火) 09:25:11
>>777
ごめんC++の限界
0779デフォルトの名無しさん2005/08/09(火) 10:32:04
>>777
配列の代わりにvectorを使うとか
0780デフォルトの名無しさん2005/08/09(火) 12:05:02
RGB → BGR 変換ってどうやったらいいでしょうか?
0781デフォルトの名無しさん2005/08/09(火) 12:15:15
C++にはRGBもBGRもありません。
0782デフォルトの名無しさん2005/08/09(火) 12:16:04
>>780 シラネーヨ
0783デフォルトの名無しさん2005/08/09(火) 12:33:33
RGB→BGR変換って、
RGB old;
BGR new;
new.b = old.b;
new.g = old.g;
new.r = old.r;
ってこと?
どうやるもへったくれもなさそうなんだけど。
0784デフォルトの名無しさん2005/08/09(火) 13:56:28
つまらんネタでひっぱらなくてよろし
■ このスレッドは過去ログ倉庫に格納されています