■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 part26
251 名前:デフォルトの名無しさん :03/12/13 01:14
using N::A;
int main()
{
asm ;
delete new N::S((A&)A("Hello world"));
return 0;
}


252 名前:デフォルトの名無しさん :03/12/16 01:08
class Base {};

class Inheritance1 : public Base {};
class Inheritance2 : public Base {};

int main(int argc, char **argv)
{
Base *instance;
switch(argv[1]){
case 1:
Base = new Inheritance1;
break;
case 2:
Base = new Inheritance2;
break;
}
}
って言うのを巧く書く方法無いですか?
継承クラスが増えてからcase書き加えていくのだるいんですけど。

int main(int argc, char **argv)
{
argv[1] instance;
}
みたいなの。

253 名前:デフォルトの名無しさん :03/12/16 01:15
>>252
そのコードは根本的に間違ってるとは思うが。

文字列から対応するオブジェクトを生成させるために新しいオブジェクトを返す
関数ポインタや関数オブジェクトをstd::mapに格納するつーのはあるが。

254 名前:デフォルトの名無しさん :03/12/16 01:18
>>252
int 値を受けて、実際のクラスを作るファクトリクラスを用意。

class Base;

class Factory {
public:
  typedef Base* (*FACTORY_METHOD)();
  void addClass(int class_id, FACTORY_METHOD f);
  Base* CreateInstance(int class_id);

  // singleton
  static Factory& GetInstance();
};

#define g_factory (Factory::GetInstance())

で、こいつに派生クラスのインスタンスを作成するメソッドを順次登録していく。

static Base* Create1() { return new Inheritance1; }
static Base* Create2() { return new Inheritance2; }

g_factory.add(1, Create1);
g_factory.add(2, Create2);
...

もちろん、手作業で Create1 とか g_factory.add() なんてのを書き並べていくのは
ダサイから、そこはマクロと static 変数を使って小細工する。

255 名前:252 :03/12/16 01:28
Base = new って間違えてましたね。すいません。

>>254 ありがとうございます。眠いので明日やってみます。
よければ、そのマクロとstatic変数を使った小細工も教えてくだされ。

256 名前:デフォルトの名無しさん :03/12/16 02:22
#include <iostream>
#include <loki/typelist.h>
#include <boost/shared_ptr.hpp>
template<typename TList,typename _Base>class FactoryImpl{
private:
  typedef _Base Base;
  template <typename TList2,typename Base2> friend class Factory;
  template <typename TList2,typename Base2> friend class FactoryImpl;
  static Base * Create(){return new typename TList::Head;}
  template <typename TList2>
  static inline void Init(Factory<TList2,Base> * factory,unsigned int ID){
    factory->m_factoryfn[ID]=Create;
    FactoryImpl<typename TList::Tail,Base>::Init(factory,ID+1);
  }
};
template<typename _Base>class FactoryImpl<Loki::NullType,_Base>{
private:
  template <typename TList2,typename Base2> friend class FactoryImpl;
  template <typename TList2>
  static inline void Init(Factory<TList2,_Base> * factory,unsigned int ID){}
};


257 名前:デフォルトの名無しさん :03/12/16 02:23
template <typename TList,typename _Base>
class Factory{
public:
  typedef _Base Base;

  template <typename TList2,typename Base2>friend class FactoryImpl;
  Base * (*m_factoryfn[Loki::TL::Length<TList>::value])();
public:
  Factory(){
    FactoryImpl<TList,Base>::Init(this,0);
  }
  Base * Create(unsigned int id){
    return m_factoryfn[id]();
  }
};
class Base{public:virtual void print()=0;virtual ~Base(){}};
class Test0:public Base{public:void print(){std::cout << "Test0\n";}};
class Test1:public Base{public:void print(){std::cout << "Test1\n";}};
class Test2:public Base{public:void print(){std::cout << "Test2\n";}};
int main(){
  typedef Factory< TYPELIST_3(Test0,Test1,Test2) ,Base> Factory;
  Factory factory;
  boost::shared_ptr<Base> p(factory.Create(1));
  p->print();
  std::cin.get();
  return 0;
}



258 名前:デフォルトの名無しさん :03/12/16 02:28
いぜん作りかけたやつだけど、LokiにもFactoryあるし。
FactoryそのものはLokiのやつ使って登録だけ楽に出来るユーリティーにしてもいいかな。


259 名前:デフォルトの名無しさん :03/12/16 02:37
このぐらいだとFactory作る手間よりもとのコードに case 加えてるほうが
シンプルで間違いにくくて手間も少ない、よねえ。

260 名前:259 :03/12/16 02:43
factory は作る。中身は元の switch 突っ込む、が正しいか。

261 名前:デフォルトの名無しさん :03/12/16 02:49
>>259
クラス増えても
typedef Factory< TYPELIST_20(Test0,Test1,Test2,Test3,Test4,Test5,Test6,Test7,Test8,Test9,Test10,
  Test11,Test12,Test13,Test14,Test15,Test16,Test17,Test18,Test19) ,Base > Factory;
Factory factory;
factory.Create(19);

ついでに
template <typename T0,typename T1=Loki::NullType,typename T2=Loki::NullType>
struct GenTypelist{
  typedef Loki::Typelist<T0,typename GenTypelist<T1,T2,Loki::NullType>::Result> Result;
};
template<>
struct GenTypelist<Loki::NullType,Loki::NullType,Loki::NullType>{
  typedef Loki::NullType Result;
};
これのもっと数増やしたやつ使えば数字入りマクロ使う必要もなくなるし。


262 名前:デフォルトの名無しさん :03/12/16 13:57
std::vectorとboost::arrayの中間の機能のものを探しています。
あらかじめ上限が決まっていて、newやdeleteを呼び出さないvectorが欲しいのですが、
どこかにあるでしょうか?

263 名前:デフォルトの名無しさん :03/12/16 14:04
>>262
即興で書いてみたがこんなの?

template<typename T, int SIZE> class fixed_array {
T v_[SIZE];
public:
typedef T * iterator;
typedef const T * const_iterator;
typedef size_t size_type;
const_iterator begin() const { return v_; }
const_iterator end() const { return v_ + SIZE; }
iterator begin() { return v_; }
iterator end() { return v_ + SIZE; }
size_type size() const { return SIZE; }
T& operator [](int index) { return v_[index]; }
const T& operator [](int index) const { return v_[index]; }
T& front() { return v_[0]; }
T& back() { return v_[SIZE-1]; }
// 以下適宜
};


264 名前:デフォルトの名無しさん :03/12/16 14:13
>>263
そりゃ、まんま boost::array でんがな。

265 名前:デフォルトの名無しさん :03/12/16 14:23
error C2018: 文字 '0x40' は認識できません。
このエラーってどうして出るの???

266 名前:デフォルトの名無しさん :03/12/16 14:35
>>265
「C2018」でぐぐれ

267 名前:デフォルトの名無しさん :03/12/16 17:05
全角スペース (SJIS で 0x8140 だっけ?) とかがソースに混入してるんじゃないの?

268 名前:デフォルトの名無しさん :03/12/16 17:26
>>262
std::vectorを最初にresizeでメモリ確保してして、push_back使わなければいいだけでは?
ていうか、上限きまってるならboost::arrayで十分だと思うんですが?

269 名前:デフォルトの名無しさん :03/12/16 17:55

LAN内にある他のパソコンに接続されたUSBカメラの動画を
リアルタイムで表示させたいのですがどのようにすればいいでしょうか?
ヒントや関連サイトなどありませんでしょうか

270 名前:262 :03/12/16 19:19
>>268
最初の1回すらnewを呼ばせたくないけど、push_back()は使いたいんです。
上限超えたpush_back()は例外投げるしかないでしょうね。
boost::arrayって上限固定ではなく、サイズ固定ですよね。
自前で書いても良いのですが、車輪の再発明をして恥を書く前に聞いてみたわけです。
組み込み系やコンシューマーゲームでは需要があるかも。

271 名前:デフォルトの名無しさん :03/12/16 20:32
>>270
boostに上げてくれると最高

272 名前:デフォルトの名無しさん :03/12/16 20:37
capacity固定でsize可変ってことですよね?
ちょっと考えてみましたが、少なくとも
std::vectorやboost::arrayを使った実装はできませんね。

273 名前:デフォルトの名無しさん :03/12/16 21:56
というわけで、自作が一番ええんやないかな。

274 名前:デフォルトの名無しさん :03/12/16 21:57
boost::arrayをstd::vectorっぽく改造するのが一番手っ取り早そうだな。

275 名前:デフォルトの名無しさん :03/12/16 23:07
>>270
> 最初の1回すらnewを呼ばせたくない
std::vecotr の第二引数でアロケータを指定できるが (標準だと std::allocator が使われる)、
これを自作のものに差し替えれば。

276 名前:デフォルトの名無しさん :03/12/17 00:17
> また、テンプレートライブラリ(STL含む)に関する質問は
> 専用の別スレへどうぞ。
ttp://pc2.2ch.net/test/read.cgi/tech/1066493064/l50


277 名前:252 :03/12/17 00:34
>>256>>257 ありがとうございます。
#include <loki/Typelist.h>
template <typename TList,typename _Base> class Factory; //前方宣言
の修正加えたら動きました。悲しいかな意味がよく分かりませんが・・・
取り敢えず、Typelistでも追ってみます。

278 名前:デフォルトの名無しさん :03/12/17 00:47
ある規定クラスBから派生したクラスD1,D2,D3,D4があるとして、
これらを(何でもいいですが)コンテナクラスに格納してるとします。

で、ファイルにこれらの格納されている要素を
それぞれのクラスごとに形式を決めて書き出したとして、
読み出し&再生成&再格納する際は結局
その形式(クラスごとのIDなど)でswitch-caseするしかないんでしょうか。

仮想コンストラクタの例で上のような仕事をするメンバ関数について
More Effective C++などでも若干触れられていますが、
詳細な実装についてはまったく言及されていません。

switch-caseしてしまうと、クラスD5,D6...と形式追加されたときに
この仮想コンストラクタもメンテせねばならず、
オブジェクト指向っぽくありません。

玄人の皆さんはどのようにクラス設計されているのでしょうか?

279 名前:デフォルトの名無しさん :03/12/17 01:10
>>278
んー? ちょっとまって。
確認しておきたい。

コンテナクラスに格納ってのは
同じ基底クラスのコンテナにポインタ使って格納してるの?

逆に、クラスごとに形式を決めて描き出す、ってのは
クラスごとに別のファイルに書くのか、
クラスごとに別々にブロック分けされてるのか、
それともコンテナ内での順位を保ったまま
無秩序に(実際のクラス関係なく)吐き出されてるの?

どうも自己完結気味に書かれてて
若干意図が読みとりにくいんだけど。

280 名前:デフォルトの名無しさん :03/12/17 01:13
>>278
MFCのCObjectのシリアル化が参考になるかも

281 名前:278 :03/12/17 01:40
まだコーディングし始めたわけじゃないんですが、

>>コンテナクラスに格納ってのは
>>同じ基底クラスのコンテナにポインタ使って格納してるの?

そのとおりの実装を想定してます。

>>逆に、クラスごとに形式を決めて描き出す、ってのは

については最後の

>>それともコンテナ内での順位を保ったまま
>>無秩序に(実際のクラス関係なく)吐き出されてるの?

に該当します。1ファイルにコンテナ内の順序を保ったまま
吐き出すことを想定しています。

説明不足気味で申し訳ない。

>>280

処理系がVC++じゃないんで、MFCは参照できないですねー。
シリアル化(シリアライズ)ってよく目にしますけど、どういうものですか?


282 名前:デフォルトの名無しさん :03/12/17 01:41
シリアル化って日本語で言うんだ。
そのままシリアライズって言ってた。
どれくらい高レベルのシリアライズを要求してるのかね。

正直ファイルに書かれた時点で型情報失うんだから
なんらかの識別子は必須なんだけど、、、それわかってるのかなあ。
詳細詳細言う割には自分のクラスのファイル出力のことが抜け落ちてやしない?

さらに言えば
識別子を含めてファイルフォーマットを管理する
クラスを挟む必要があるわけだし。
もちろんそいつ自身がアブストラクト・ファクトリであってもいいけれど
すでに型情報があるのならそこからクラスごとのファクトリメソッドを呼べばいいわけで
その時点で引数までに共通性を求める仮想コンストラクタを要求する必要がなくなってしまうという話。


283 名前:デフォルトの名無しさん :03/12/17 01:48
ああ、高レベルさってのはさ、たとえば
たとえばファクトリメソッドの中でファクトリメソッドを呼び出す処理をする必要があるのかとかね。
つまり、
Class A
{
SubA1 sa1_;
SubA2 sa2_;
public:
A(SubA1 sa1, SubA2 sa2)
: sa1_(sa1), sa2_(sa2) {;}
}
みたいなクラスがあったときは当然深いコピーがいるでしょ?
メンバがすべて基本型だという保障があるか、
クラスのコンストラクタが含めてすべて引数が基本型になっててメンバの面倒までみる
( A(double m11, int m12, char m21) : sa1_(m11,m12), sa2_(m21) {;} みたいに)
のならこんなことは考えなくてもいいわけだけど。


284 名前:デフォルトの名無しさん :03/12/17 01:53
具体的なのフォーマットはたとえば
高レベルな場合、
(A
(SubA
(double 1.0)
(int 1024)
)
(SubB
(char 38)
)
)
低レベルかつ引数の型が固定の場合なら
A 1.0 1024 38
なんかでいい。
もちろん引数を読む前に型識別子がいる。


285 名前:278 :03/12/17 02:59
>>282-284

長文解説ありがとうございます。
で、個人的には詳細な実装を求めているわけではなくて、
278にも書いたとおり、ファイルからの読み込み+インスタンスの再生成
ではswitch-caseに頼るしかないのか否か、ということです。

>>正直ファイルに書かれた時点で型情報失うんだから
>>なんらかの識別子は必須なんだけど、、、それわかってるのかなあ。

識別子を書き出すということは278でも書いているのですが、
この値を元にインスタンスを再生成ということは、
やはり switch-case で実装するということですか?

#>>284でファイルフォーマット例を挙げておられますが、
#たとえばこれを読み込むメソッドがどう実装されるのか、
#switch-caseを使ってA,A',A''を生成することのなるのか、
#A'''があたらに追加された場合、読み込む箇所も変更が
#必要となるのかが知りたいわけです。


286 名前:278 :03/12/17 03:07
ちなみになぜこんなことを気にしだしたのかといえば、
書き込みの場合は格納されるクラス群に
例えばWriteMyself(...)の様な仮想関数を実装しておけば、
あとはコンテナの要素をそのまま全部なめながら
このメソッドをコールすれば済むのに
(もちろん新しいクラスを追加しても問題なし)、
読み込みはそうはいかないな、と考えたのが発端です。

#またわかりにくいですかね?


287 名前:デフォルトの名無しさん :03/12/17 05:26
ああクラス側で読み書きをそれぞれ分散して管理したいのか。
シリアライズの場合は一カ所に集めた方がいいと思うけど。

そういうことだったら
std::ofstream& operator << (std::ofstream& fin, const SomeClass& something);
に対して
virtual
std:oifstream& SomeClass::ofstream& Write(std::ofstream& fout) {
return fout << *this;
}
を用意して仮想化してやるように

std::ifstream& operator >> (std::ifstream& fin, SomeClass& something);

virtual
ifstream& SomeClass::ifstream& Read(ifstream& fin) {
return fin >> *this;
}

とやればできるんじゃない?
ただこのまま使うとデフォルトコンストラクタ呼んだ後に代入することになっちゃうけど

288 名前:デフォルトの名無しさん :03/12/17 09:49
>278
書き込みについては仮想関数で一発だけど、
読み込みについては、何らかのID->クラスのマッピングは
必要になる。(switch-caseはそのマッピング実装の一つ)

289 名前:デフォルトの名無しさん :03/12/17 12:46
x86 で long double って何bitですか?

290 名前:デフォルトの名無しさん :03/12/17 12:51
>>289
sizeofすればわかるだろ

291 名前:デフォルトの名無しさん :03/12/17 13:22
CPU的にはIA-32では単精度32bit倍精度64bit拡張精度80bit。

ただしVC++の場合は32/64/64だったりするのでx86一般の話は不可能。

292 名前:デフォルトの名無しさん :03/12/17 14:33
>>291
そうですか。gccだとどうなんだろ。sizeofしてみるか

293 名前:デフォルトの名無しさん :03/12/17 21:01
>>285
> 278にも書いたとおり、ファイルからの読み込み+インスタンスの再生成
> ではswitch-caseに頼るしかないのか否か、ということです。
必ずしも switch - case で実装する必要はない。たとえば、非ローカル static オブジェクトを
利用して main 実行直前に ID -> クラスの対応表を作成する方法がある。

いまバイト列を読んで、B の派生クラス D1, D2, .. を実際に復元する関数を

 B* CreateD1(void const*); B* CreateD2(void const*);

としよう。まずは、これと ID の対応付けを行うクラスを用意する。各 ID は 128bit ぐらいの
長いデータにして、絶対に重複しないアルゴリズムを使って生成し、D1, D2, ... 各クラスに
static const メンバ変数として定義しておくのが良い。

typedef unsigned long long B_CLSID_TYPE; // D1, D2, ... 各派生クラスの固有 ID
typedef B* (*B_CREATOR_TYPE)(void const*); // D1, D2, .. 各派生クラスを new する関数

class BFactory {
public:
  // 復元関数を登録する
  void add(B_CLSID_TYPE magic, B_CREATOR_TYPE create_func);
  // ID からクラスを特定して、オブジェクトを復元する, 事前に add() で登録した関数を呼べば OK
  B* create(B_CLSID_TYPE magic, void const* data);
  // singleton
  static BFactory& GetInstance() { static BFactory factory; return factory; }
};

#define g_BFactory (BFactory::GetInstance())


294 名前:293 :03/12/17 21:05
これで、後は誰かが

 g_BFactory.add(1, CreateD1);
 g_BFactory.add(2, CreateD2);

とか呼んでおけば良いわけだ。

ここで D1, D2, ... それぞれの派生クラスを実装しているファイル d1.cpp, d2.cpp に
次のようなクラスと変数の定義を付け加える。

struct D1AddToFactory {
  D1AddToFactory() {
    g_BFactory.add(1, CreateD1);
  }
};

static D1AddToFactory d1addToFactory;

これで main 実行前に static 変数 d1addToFactory が構築され、そのコンストラクタで
BFactory クラスのシングルトンインスタンスに D1 クラスの ID, オブジェクト生成関数が
対で登録される。

main 関数が実行されたときには、すでに g_BFactory.create() で、シリアライズした
オブジェクトが復元可能になっている。

295 名前:デフォルトの名無しさん :03/12/17 21:07
まだ作りかけだけどLokiのFactory用のユーリティを作ってみた。
ttp://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/readres.cgi?bo=lounge&vi=999294620&res=114&fi=no

生成されるクラスがBaseImplから継承する必要があること、IDに今のところint型とかしか使えないこと、などの制限はあるけど。
仮想関数GetClassIdが半自動でインプリメントされるようになっている。
使い方としては
class Base:public BaseRootImpl<int>{
public:
    virtual void print()=0;
    //typedef int IdentifierType;
    //virtual int GetClassId()=0;
    //virtual ~Base(){}
};
class Test0:public BaseImpl<Test0,Base>{
public:
    void print(){std::cout << "Test0\n";}
};
class Test1:public BaseImpl<Test1,Base>{
public:
    void print(){std::cout << "Test1\n";}
};
int main(){
    Loki::Factory<Base,int> factory;
    FactortyRegister<GenTypelist<Test0,Test1>::Result>(factory,0);//2つ目の引数からタイプリスト内のIDが連番で登録される、さらにgetClassIdが使えるようになる
    boost::shared_ptr<Base> p(factory.CreateObject(1));
    p->print();
    return 0;
}


296 名前:デフォルトの名無しさん :03/12/17 21:30
出力ストリームに対して<<演算子をオーバーロードしたのですが、??なことが発生しました。
先輩方、原因が何か御教授願えますでしょうか・・・? 長くてすみません

状況: myclassを定義。myclass同士の和、myclassの出力(std::cout)に関し演算子をオーバーロード
症状: 和、出力ともに単体で正常動作。しかし「和を出力」しようとするとギタギタに怒られる
環境: g++ 3.3.1 (on cygwin)
ソース:
#include<iostream>
class myclass { public: int x,y; };

myclass operator+(myclass &c1, myclass &c2){
myclass t;
t.x = c1.x + c2.y; t.y = c1.y + c2.y;
return t; }

std::ostream& operator<<(std::ostream& os, myclass &c1){
os << "x: " << c1.x << std::endl; os << "y: " << c1.y << std::endl;
return os; }

int main(void){
myclass m1,m2,m3;
m1.x = 100; m1.y = 101; m2.x = 102; m2.y = 97;
m3 = m1 + m2;//問題なし
std::cout << m3;//問題なし
std::cout << (m1+m2);// めちゃめちゃ怒られる
return 0; }

297 名前:デフォルトの名無しさん :03/12/17 21:34
>>296
× std::ostream& operator<<(std::ostream& os, myclass &c1){
○ std::ostream& operator<<(std::ostream& os, const myclass &c1){

ついでに
× myclass operator+(myclass &c1, myclass &c2){
○ myclass operator+(const myclass &c1, cosnt myclass &c2){

関数の中で引数に変更を加えないなら、全部const参照にすること。
でないと、constオブジェクトとか一時オブジェクトとかを使えなくなる。

298 名前:278 :03/12/18 01:28
>>287

むー、でも、この仮想関数Readを呼び出すインスタンス
はどうやって決めればいいのでしょうか?というか、そこが肝なんですが。
なんか解釈が間違ってます?

>>288

端的な回答ありがとうございます。コストとリターン、やりたいことの
兼ね合いも考えて、>>293-294のソースも参考にしつつ実装方針を
決めることにします。

>>293-294

ひゃー、詳細な解説ありがとうございます。
中身を見て、参考にさせていただきます。

ありがとうございます。いつか恩返しできればいいのですが。


299 名前:デフォルトの名無しさん :03/12/18 01:57
仮想関数呼び出しをするということは
その時点でクラスが構築されていないといけない。当たり前。
仮想関数を呼び出してる時点で
事前にその型のインスタンスの割り当てと初期化は行われている。
これが行うのはあくまで値の設定部分のみ。

クラスごとにシリアライズ用のメソッドを用意した場合の利点は、
READとWRITEの書式(当然復元可能である必要がある)を
クラスごとに管理できるってことの方。
マッピングはそれ以前に別のオブジェクトやら関数で行う必要があるって
再三言われてるんだけどまだ納得していなかったのか。

だいたい
クラスAの出力 10, 2.0 と
クラスBの出力 10, 2.0 を
それ単体で区別するなんて常識で考えても不可能でしょうに。

ちなみにマッピング方法はC++じゃ
>>293が挙げてるようなファクトリクラスを作るのが一般的だけれど
クラス自体がオブジェクトとして振る舞えて動的束縛に強い言語なら
また別なオブジェクト指向らしいやり方も存在する。
C++でも仮想クラスメソッドが持てればいいんだけどねえ……

300 名前:296 :03/12/18 12:36
>>297
うまくいきました!どうもありがとうございます。
お教えに従いまして、意識してconstを使うように致しますです。

301 名前:デフォルトの名無しさん :03/12/18 18:37
そんなことよりX'masって「'」はつけないんだけどね・・・
正しくはXmas。
そこの君。知ったかぶって恥をかかないようにね。

302 名前:デフォルトの名無しさん :03/12/18 18:48
Xmas の X は実はギリシャ語のカイである。
ギリシャ語でのクリスマスの頭文字である。
それを聞くと一見 X は略になってるから
アポストロフィを付けても良さそうである。
しかし、Xmas は Christmas を直接略したものではないので、
アポストロフィはつけないのである。
だから、Χ'μασ なら許されるかもしれない。

303 名前:デフォルトの名無しさん :03/12/18 18:53
>> そんなことよりX'masって「'」はつけないんだけどね・・・
ソースを示せ。

304 名前:デフォルトの名無しさん :03/12/18 18:59
>>303
http://www2.alc.co.jp/ejr/index.php?word_in=xmas&word_in2=%82%A9%82%AB%82%AD%82%AF%82%B1&word_in3=3nIUYPfHrHCqvs7ZxZ

305 名前:デフォルトの名無しさん :03/12/18 19:05
ヘー(・∀・)⊇

306 名前:デフォルトの名無しさん :03/12/18 19:06
常識じゃん。

307 名前:デフォルトの名無しさん :03/12/18 19:46
Xmasを辞書で引けば書いてる。

308 名前:デフォルトの名無しさん :03/12/19 01:11
俺の辞書にXmasなんて文字は存在しない

309 名前:デフォルトの名無しさん :03/12/19 01:29
俺のカレンダーにもない。

310 名前:デフォルトの名無しさん :03/12/19 02:00
つーかXmasは文字じゃなくて文字列だろ。

311 名前:デフォルトの名無しさん :03/12/19 05:12
Xmasなんて書くのは日本人だけ。
他の国ではきちんとChristmasと書いている。

312 名前:デフォルトの名無しさん :03/12/19 05:24
http://user.auctions.shopping.yahoo.com/user/schmoo39sgreatdeals4u
この季節は日本人大もうけだなw


313 名前:デフォルトの名無しさん :03/12/19 05:55
  \|/
  /⌒ヽ  / ̄ ̄ ̄ ̄ ̄ ̄ ̄
 │ ゚Θ゚)< そうでもないよ
 │ ∵ つ  \_______
 │ ∵ │
  \_/

>>311
http://search.yahoo.com/search?p=xmas

314 名前:デフォルトの名無しさん :03/12/19 09:20
俺の辞書にはクルシミマスと言う単語ならある。

315 名前:デフォルトの名無しさん :03/12/19 10:03
殆どの人は Xmas か X-mas と書く。
外国でも英語圏でなければ X'mas と書く人も見かけるけど。

316 名前:デフォルトの名無しさん :03/12/19 20:02
毒男板か、ここはw

317 名前:デフォルトの名無しさん :03/12/20 03:07
殆どの人は XMEN か X-MEN と書く。
外国でも英語圏でなければ X'MEN と書く人も見かけるけど。


318 名前:デフォルトの名無しさん :03/12/20 03:56
本を読んでると

inline istream& operator>>(istream &io, String &s)
{
  const int limit_string_size = 4096;
  char inBuf[limit_string_size];
  io >> setw(limit_string_size) >> inBuf;
  s = inBuf;
  return io; // String::operator=(const char*);
}

というソースがあったのですが
こういう場合inBufの確保にnewを使わないのはdeleteしなくていい他に何か理由があるのでしょうか?

319 名前:デフォルトの名無しさん :03/12/20 05:51
>>318
スタックの上限に十分収まり、入力される文字の上限が
プログラム時に決まっているのなら静的配列で構わん。
staticにしないとバッファが使い回せないという問題はあるが
まだそんなことを気にする段階ではないようだし。

もひとつおせっかいすると
newで確保するのも根本的な解決にはならないぞ。
実行時に指定されたデータ数分だけ最初に確保したら
それ以降の自動的な拡張は行われないからな。

一時的にストリームから読み込んで何やらしたいのなら
streambufを使うのが常道。
せめてstringやvector<char>なんかを使った方がいい。

320 名前:デフォルトの名無しさん :03/12/20 05:57
というかストリームからchar配列に指定文字数読み込むのにそんな書き方……。
学習進度にもよるが、get/getline/readなんかを文字数以外の終了条件に応じて使うことを勧める。

321 名前:318 :03/12/20 07:10
詳しいレスありがd。
ストリーム読み取りに他の王道があるというのはとりあえずおいておいて

>>319-320
ということはnewでメモリを確保するのに比べて

char inBuf[limit_string_size];

は、書くのが楽な以外にメリットはないってことでしょうか?
結構ちらほら見るので何か理由があるのかなーと思って。
スタックの上限もあることだし、デメリットだけなのかな・・・。

322 名前:デフォルトの名無しさん :03/12/20 07:25
>>321
ふつうは、実行時のパフォーマンスがいい。
あと、例外安全。

323 名前:デフォルトの名無しさん :03/12/20 07:45
1.スタックよりヒープの方が確保/解放等にコストがかからない。
2.newは失敗する可能性を常に考慮にいれないといけない。
3.newで確保したメモリは必ず解放しないといけないが、
  複数のreturn文や内部のプロセスで例外が投げられたときに
  解放し損ねてリークすることがある。
勘違いしているようだが静的確保で済む場合は静的確保がデフォ。

324 名前:デフォルトの名無しさん :03/12/20 09:22
>>323
1は逆じゃない?
3はスマートポインタに突っ込んどくと楽。

325 名前:デフォルトの名無しさん :03/12/20 09:46
>>324
あ、ホントに逆だね。サンクス。
3のリソース管理は本当に必要ならスマートポインタ使うべきだけど
今回のようなものならそもそもSTLのコンテナなんかを使うべきところでしょう。
それに半端に勘違いしてstd::auto_ptrとか使うとdelete[]とdeleteの違いで
かえって困ることになりかねないから書かなかった。

326 名前:デフォルトの名無しさん :03/12/20 10:27
>>322
>あと、例外安全。

まず、漏れも人のことは言えんと白状しておく。

newの失敗を気にするくせに
スタックのあふれは考えようともしないのは
非科学的だと思う。

スタックの最大使用量をきっちり計算して
定義ファイル書いてる香具師どんくらいいる?

327 名前:デフォルトの名無しさん :03/12/20 10:37
つーかきちんと考えてるならローカルにバッファなんて作らないと思う。
問題の前提崩れてしまうぞ。
一元的に確保したものをplacement newや類似の仕組みで
切り分けたり使い回したりしない?
釈迦に説法かもしれないけど。

328 名前:デフォルトの名無しさん :03/12/20 10:51
>>326
> スタックの最大使用量をきっちり計算して
全体を通しての計算はしていない。

再帰呼び出しが発生する部分だけ見積もりをとり、あと実機で動くプログラムに
細工してスタック使用量を実行時にモニタリング。最後に、その数値を使って
スタックファイル調整してる。

329 名前:デフォルトの名無しさん :03/12/20 11:21
スタックオーバーフローなんて気にしたことなかったなぁ…。
#include <iostream>
void foo(int x){
  try{
    foo(x+1);
  }
  catch(...){
    std::cout << "exception at " << x + 1 << std::endl;
  }
}

int main(){
  foo(0);
}

試しにやってみたら、ちゃんとスタックオーバーフローするのな。

330 名前:デフォルトの名無しさん :03/12/20 15:26
>>328
なるほどなー
テスト後にコア吐かせるかdiagモードでリブートしてRAMのケツをタシーロとか
スタックチェック埋め込んどいてあぼーん確定らしいときは守りに入るとか...

331 名前:デフォルトの名無しさん :03/12/21 01:50
GUI使ったアプリをそろそろ作りたくなってきました
C++の開発環境を導入しようと思うのですが
現在VC++7.1とBorlandC++builder6.0で悩んでいます
両方使ったご経験のある方それぞれの長所をご教授ください

332 名前:318 :03/12/21 02:02
いろいろレスありがとうございます。
まとめると

・スタックに確保は実行時のパフォーマンスがいい。
・newもスタックに確保する場合も失敗する可能性を常に考慮にいれないといけない。
・newで確保したメモリは必ず解放しないといけないが例外処理がめんどう。

そこで普通は

・スマートポインタやplacement newを使う。

placement newって知らなかった_| ̄|○
基本くさいなのに。

セキュリティ的には固定長バッファをスタックに積むだけであぼんな可能性を常に考慮しなくてはいけないし
かつ、マの負担を考えても前時代的な手法と思っていたのですが
ソースを見るといっこうに減らないので単に漏れが知らない何か理由があるのかな?と思ったわけです。
組み込み系を書いてる人はまた違う意見持ってそうなのでちょっと聞きたかったかな。

333 名前:デフォルトの名無しさん :03/12/21 02:15
>>331
C++Builderは事実上死んだ(C++BuilderXはほとんど別物)んで
わざわざ買うならVC++のほうがいいとは思うが、そもそも趣味でやる程度なら
BCCやMingw(どっちもC++BuilderX Personalに入ってるが)で適当なGUIライブラリ
(それこそwxWindows)でもつついてりゃいいんじゃないか?

334 名前:デフォルトの名無しさん :03/12/21 08:53
winny2もC++Builderで作ったらしいね

335 名前:デフォルトの名無しさん :03/12/21 11:19
GUIをさっくり作りたいんなら今でもC++Builderはオススメですよ。
可能なら両方買っておきたいけど。

336 名前:デフォルトの名無しさん :03/12/21 14:22

C++のクラスのprivateメンバに文字列定数と
RECT構造体の定数を含ませたいのですが、

class hoge {
   static const char strName[] = "おまえモナー";
   static const RECT rectangle = { 100, 100, 200, 200}
};

これですと、エラーになってしまいます。

const や static にこだわらずに、一般の変数として
宣言してコンストラクタでデフォルト値を代入すれば
問題ないと思うのですが、せっかくなので const
や static をつけたメンバ変数を宣言(定義?)すること
はできないのでしょうか?

stroustrupの本ではstatic constは整数にだけ認められて
いるみたいです。
(例)
class hoge {
  static const int = 100;
};

クラスに固有の文字列定数を持たせたい場合には
どうしますか?

337 名前:デフォルトの名無しさん :03/12/21 14:25
>>336
   static const RECT rectangle = { 100, 100, 200, 200}
この部分、最後に ; が付きます。

どっちにしろエラーですが。

338 名前:デフォルトの名無しさん :03/12/21 14:30
>>336
・constでもコンストラクタの初期化記述で書ける
class hoge {
 const std::string strName;
public:
 hoge():strName("おまえモナー") {}
};


・staticなら初期化文は別途モジュール作って定義する
//hoge.h
class hoge {
 static const std::string strName; // 外部リンケージ宣言
};
//hoge.cpp
const std::string hoge::strName = "おまえモナー"; // 実体定義


339 名前:デフォルトの名無しさん :03/12/21 14:34
>>336
template<char* s>class StrTaker{};


340 名前:デフォルトの名無しさん :03/12/21 14:34
const char hoge::strName[] = "(*゚ー゚)ダッコ♪";

341 名前:デフォルトの名無しさん :03/12/21 14:46
>>338
なるほど。ありがとうございました。
実体定義のときには static は付けてはいけないのですね。

以下のようにchar配列を使っても、エラー無しでコンパイルできました。

#include <windows.h>

class hoge {
   static const char strName[];
   static const RECT rectangle;
};

const char hoge::strName[] = "おまえモナー";
const RECT hoge::rectangle = { 100, 100, 200, 200 };



342 名前:デフォルトの名無しさん :03/12/21 14:56
>>341
え。常識じゃん。

343 名前:デフォルトの名無しさん :03/12/21 15:03
> 実体定義のときには static は付けてはいけないのですね。

「staticなら初期化文は別途モジュール作って定義する」って書いてあるのに、
なんでそうなるんだ。

344 名前:デフォルトの名無しさん :03/12/21 15:25
class A
{
#include <pshpack1.h>
public:
 struct B
 {
  char x;
  int y;
 };
#include <poppack.h>
};

A::Bだけアライン変更してます。
VC++6.0でコンパイルできましたが、これは言語規格的にいいのでしょうか?
#include がクラス宣言内で出てくるのは今まで見たこと無いので自信ないです。

345 名前:デフォルトの名無しさん :03/12/21 15:37
#include自体は問答無用で内容ぶちまけるだけだから問題はない。
アライン云々は実装依存なので規格上はしったこっちゃないな。

346 名前:デフォルトの名無しさん :03/12/21 15:42
>>345
>#include自体は問答無用で内容ぶちまけるだけ
納得しました。ありがとう。

347 名前:デフォルトの名無しさん :03/12/21 23:27
>>346
ttp://www.tietew.jp/cppll/archive/5730
こんな使い方もありです。

348 名前:331 :03/12/21 23:56
333さん334さん335さん
ご意見と情報ありがとうございましたm(__)m


349 名前:デフォルトの名無しさん :03/12/22 18:37
23日の夜を、クリスマスイブイブって得意顔で言うおっちゃんっているよなw


350 名前:デフォルトの名無しさん :03/12/23 02:22
いるか?

351 名前:デフォルトの名無しさん :03/12/23 07:44

☆★☆★★☆ラッキーレス☆★★☆★☆

    ⊂⊃     .☆.。.:*・゜
(\ ∧_∧   /
(ヾ ( ´∀`)/ このレスに出会ったあなたは超ラッキー。
''//( つ ● つ
(/(/___|″ 近々幸運が舞い込んでくることでしょう。
   し′し′    

☆★☆★★☆ラッキーレス☆★★☆★☆


352 名前:デフォルトの名無しさん :03/12/23 12:24
>>349自身のことではなにの?

353 名前:デフォルトの名無しさん :03/12/23 13:47
VC++6.0の場合

void func()
{
 AAA a1, a2;
 BBB b1, b2;
}

とした場合、スコープから抜けたときデストラクタが呼ばれる順序は
生成順の逆b2, b1, a2, a1となりました。
また、

class CCC
{
public:
 AAA a1, a2;
 BBB b1, b2;
};

CCC c;

とした場合も、cがスコープから抜けるとやはり生成順の逆
c, b2, b1, a2, a1の順でデストラクタが呼ばれました。

オブジェクトの解放順序は言語規則として定められているのでしょうか?
それともたまたまこうなっただけでしょうか?


354 名前:デフォルトの名無しさん :03/12/23 14:28
決まってる

355 名前:デフォルトの名無しさん :03/12/23 14:56
>>351
luckless かと思ったよ。

356 名前:デフォルトの名無しさん :03/12/23 17:10
あるクラスの非constなメンバ関数へのポインタと、constなメンバ関数へのポインタの、
どちらも引数に取ることの出来る関数を書く方法はありますか?

例えば、以下の様なクラスと関数があったとします。

class foo
{
public:
void non_const_function() {};
void const_function() const {};
};

void f(void (foo::*pf)()) {}
void g(void (foo::*pf)() const) {}

この、f()とg()をそれぞれ以下の様な引数で呼ぶと、型変換が出来ないというエラーが出ます。

f(&foo::const_function);
g(&foo::non_const_function);

gcc 3.3.2でコンパイルしたときの具体的なエラーメッセージは次の様になります。

test.cc: In function `int main()':
test.cc:15: error: cannot convert `void (foo::*)() const' to `void (foo::*)()'
   for argument `1' to `void f(void (foo::*)())'
test.cc:16: error: cannot convert `void (foo::*)()' to `void (foo::*)() const'
   for argument `1' to `void g(void (foo::*)() const)'

この様なエラーメッセージが出るのですが、foo::const_functionとfoo::non_const_functionの
どちらも引数に取ることが出来るような関数を書くことは出来るでしょうか?

357 名前:デフォルトの名無しさん :03/12/23 17:45
>>356
ポインタをconst付きにして、関数アドレスをconst_castして代入かな?
要はconstオブジェクトへの副作用が起きなければいいわけだろ

358 名前:デフォルトの名無しさん :03/12/23 17:45
あ、それは無理か
失礼

359 名前:デフォルトの名無しさん :03/12/23 20:23
>>356
テンプレートとかオーバーロードはだめなのかな?

360 名前:デフォルトの名無しさん :03/12/23 22:12
関数のローカル変数の参照をreturn;することって出来ませんか?

361 名前:デフォルトの名無しさん :03/12/23 22:21
>>360
することだけならできる。
しかし、期待した結果は得られないだろう。

参照を返すんじゃなくて、
実体を返すか、
結果を格納するオブジェクトへの参照を引数から渡すようにすべし。

362 名前:360 :03/12/23 22:27
>>361
レスありがとうございます。

関数の中でreturn;するローカル変数を作り上げて、
その実体を返した場合はメモリがちょっと無駄になりますか?

363 名前:デフォルトの名無しさん :03/12/23 22:37
戻り値最適化が働くようにコンパイラとオプションを適切に選べば平気

364 名前:デフォルトの名無しさん :03/12/23 22:39
ああただしローカル変数でもなるべく名前なしのものを返すこと。
どれだけわかりやすい記述で最適化がはたらくかはコンパイラ依存。
可能な限り return 文でコンストラクタ呼ぶようにした方がいい。

もし必ず参照で返したいと
いうのならヒープに new したものを返すしかない。

365 名前:デフォルトの名無しさん :03/12/23 22:43
処理系依存を(特に最適化に関して)無限と読む痛い連中に注意

366 名前:デフォルトの名無しさん :03/12/23 22:44
引数に出力先変数の参照を取った上でその参照を返す。

367 名前:360 :03/12/23 22:44
コンパイラとかの問題になってしまうのですか?

ところで、関数
Classname function()
の中で大きいサイズのローカルなオブジェクト
Classname obj;
を作って、
そのままreturn obj;で返す場合は、
別のメモリ領域にそのobjの情報を作って、その関数の呼び出し元がそれを受け取って、
関数で使ったローカルなobjは消滅してしまう
って認識で合ってますか?

368 名前:デフォルトの名無しさん :03/12/23 22:48
コンパイラと最適化次第やね。

369 名前:360 :03/12/23 22:55
>>364
あれ、return文でコンストラクタを呼ぶってどういうことですか?

370 名前:デフォルトの名無しさん :03/12/23 23:01
class A {
 A(int arg) {...};
};

A foo() {
 ...
 return A(4);
}

みたいな

371 名前:360 :03/12/23 23:05
>>370
ありがとうございます。
その形式は初めて見ました。
それで望みのオブジェクトを返すには
コピーコンストラクタとか使えばいいのですか?

372 名前:デフォルトの名無しさん :03/12/23 23:05
だから引数使えよ。

373 名前:デフォルトの名無しさん :03/12/23 23:13
>A foo() {

アフォー

374 名前:360 :03/12/23 23:18
return A(4);
みたいにやったら、A(4)しか返せないのではないですか?
関数内で計算したものを返せるのでしょうか。

375 名前:デフォルトの名無しさん :03/12/23 23:22
void foo(A& a) {
 a.hoge();
}



A a;
foo(a);

376 名前:デフォルトの名無しさん :03/12/23 23:37
生成後のインスタンスをいじって返すんだったら、ふつうにreturnするのが正解。
呼び出し元に返るときにコピーコンストラクタが使われる。

377 名前:デフォルトの名無しさん :03/12/23 23:43
別にもう1つ渡したんでもいいと思うが...。

378 名前:デフォルトの名無しさん :03/12/24 05:14
cin >> temp ;
while(cin.eof() == 0) {
  total += temp ;
  cout << "値を入力(終了はCtrl+Z)\n>> " ;
  cin >> temp ;
}
こんなコード書いて実行してみたら、
EOF(Ctrl+Z)を読み込んだ時点で、ループを抜けるどころか
プログラムまで抜けてしまい、終了してしまいます
こいつが原因なんですが、どこが間違ってますかね?

379 名前:デフォルトの名無しさん :03/12/24 07:49
int foo()
{
 int x = 計算式;
 return x;
}

void bar()
{
 A a(foo()); // 計算結果からAを構築
}

コピーにかかるコストを抑えたくて参照で返すとか言ってるんだろうから
このていどのコードでOK

最適化の話を注意深く調べれば

inline const A foo()
{
 int x = 計算式;
 return x;
}

void bar()
{
 A a(foo());
}
で十分なことに気づくだろう


380 名前:デフォルトの名無しさん :03/12/24 07:50
EOFをいれたきゃCtrl+D
UNIX板行ってもう一度利きなおして来い

381 名前:デフォルトの名無しさん :03/12/24 10:55
Windows では Ctrl+Z だ。

382 名前:378 :03/12/24 15:27
ぐぐったら自己解決しました
お騒がせしてすまんかった・・・

383 名前:デフォルトの名無しさん :03/12/26 01:13
お聞きしたいのですが…仮の話として

class A
{
 const int m_n;
public:
 A(const int n) : m_n(n){};
 int Get() const { return m_n; }
};

A aa[10]; // 何かしらコンストラクタに値が代入されるとします。

と、あったとして、
aa[i].Get() した値が、ある値を超えた所をfind_ifで探したい…
という場合の関数オブジェクトの作り方に悩んでいます。

bind2ndだけだと上手くいきませんし…
mem_fun系とかを使うことになるんでしょうが、どう絡めていっていいものやら…

自前で比較用の関数オブジェクトクラスを新規で作るしか、
方法はないのでしょうか?

384 名前:デフォルトの名無しさん :03/12/26 01:23
>>383
標準ライブラリのmem_funとbind系だけでは苦しいかと。
Boost.Bindで
 bind( less<int>(), 100, bind(&A::Get, _1) )
  // 100を越えてればtrue、100以下ならfalse

385 名前:デフォルトの名無しさん :03/12/26 01:36
>>383
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;
A* p = std::find_if(&aa[0], &aa[10], bind(&A::Get, _1) > 10);


386 名前:デフォルトの名無しさん :03/12/26 02:14
>>383
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/counting_iterator.hpp>
#include <iostream>
#include <algorithm>
#include <vector>
class A
{
    int m_n;
public:
    A(int n) : m_n(n){};
    //A(){m_n=0;}
    
    int Get() const { return m_n; }
};


387 名前:デフォルトの名無しさん :03/12/26 02:16
int main(){
    using namespace boost::lambda;
    using namespace std;
    vector<A> v;
    v.reserve(20);
    copy(boost::make_counting_iterator(0),boost::make_counting_iterator(20),std::back_inserter(v));//初期化
    for_each(v.begin(),v.end(),std::cout << bind(&A::Get,_1) << " ");//最初にあるデーターの中身を表示してみる
    cout << std::endl;

    //複数に分けて
    vector<A>::iterator p=find_if(v.begin(),v.end(), bind(&A::Get,_1) >5);
    vector<A>::iterator pend=std::find_if(v.rbegin(),v.rend(),bind(&A::Get,_1) <15).base();//->base());
    for_each(p,pend,std::cout << bind(&A::Get,_1) << " ");
    cout << endl;
    
    //1回でまとめて
    for_each(    find_if(v.begin(),v.end(), bind(&A::Get,_1) >5),
                find_if(v.rbegin(),v.rend(),bind(&A::Get,_1) <15).base(),
                std::cout << bind(&A::Get,_1) << " ");
    return 0;
}


388 名前:デフォルトの名無しさん :03/12/26 02:30
今ほかに思いついたけどこんなのもあり、同じの書くの大変なので一部省略
#include <boost/lambda/if.hpp>
//...
int main(){
    //...
    for_each(v.begin(),v.end(), if_( (bind(&A::Get,_1)>5 )&& (bind(&A::Get,_1) <15))[
        cout << bind(&A::Get,_1) << " "
        ]);
    return 0;
}


389 名前:383 :03/12/26 02:50
今まで boost 使った事無かったので、
VC7.1に入っているSTLだけで解決してようとしてました…

やはり、boost は使っていったほうが便利のようですね。
これから慣れていく意味でも、導入してみようと思います。


サンプルをいただけた >>384, 385, 386さん
ありがとうございます。
勉強させていただきます。

390 名前:デフォルトの名無しさん :03/12/26 03:03
>>387-388
うむ、キミがBoost.Lambdaの使い方を覚えて嬉しそうなのはわかった。
 ・とりあえず std:: はつけるのかつけないのかどっちかに統一してくれ。
 ・なんで v が sort 済みであることを仮定した話題になっているのか。
 ・これでいいじゃん
boost::transform_iterator_generator<const_mem_fun_ref_t<int,A>, vector<A>::iterator>::type
  b( v.begin(), mem_fun_ref(&A::Get) ), e( v.end(), mem_fun_ref(&A::Get) );
copy( lower_bound(b,e,6), upper_bound(b,e,14), ostream_iterator<int>(cout," ") );

391 名前:デフォルトの名無しさん :03/12/26 04:18
なんかこう、読みづらいな。

392 名前:デフォルトの名無しさん :03/12/26 04:27
>>389
Boostのlambdaがまともに通るコンパイラでよかったね。
>>391
STLもBoostも一行にぎゅっと濃縮する傾向があるから
どうしても読みにくくなるねえ。

393 名前:デフォルトの名無しさん :03/12/26 08:55
こんなのやり方わかる方いますか?
注意:以下のソース、コンパイル通らない
class CHoge1{
class CHoge2{
int m_Value2;//変数名を変える必要もないけどサンプルだし
public:
CHoge2(n){m_Vaue2 = n;}
};
int m_Value1;
const static CHoge2 m_ins[];
};

CHoge1::CHoge2 CHoge1::m_ins = {
CHoge2(3),
CHoge2(10),
};

やりたい事はクラスの中でしか使わないクラス型を作って、
メンバにstaticでその配列を持ち(実際のメンバは先頭のポインタ)
テーブルみたいに、それを使うってかんじなんですけど。
現状では、CHoge2のコンストラクタでエラーになってるみたい。
だいたいm_insの実体を作ってるところも間違ってる気がする。


394 名前:デフォルトの名無しさん :03/12/26 09:21
少なくとも
CHoge1::CHoge2 CHoge1::m_ins = {
CHoge1::CHoge2(3),
CHoge1::CHoge2(10),
};
じゃないのか。

395 名前:デフォルトの名無しさん :03/12/26 09:28
>>393
VC6 だと 以下でとおる。
const CHoge1::CHoge2 CHoge1::m_ins_a[] ={
CHoge1::CHoge2(3),
CHoge1::CHoge2(10),
};

あとは、スペルミス等直せばよし。


396 名前:395 :03/12/26 09:30
俺が変数名間違ってどうするよ。
m_ins_a -> m_ins


397 名前:デフォルトの名無しさん :03/12/26 22:07
>>393
とりあえずエラーメッセージを書こうぜ。
コンストラクタでエラーが出てるのは、
× CHoge2(n){m_Vaue2 = n;}
○ CHoge2(int n){m_Value2 = n;}
後は、>>375,376

398 名前:デフォルトの名無しさん :03/12/27 00:36
レスありがとうございます。
無事解決しました。
スペルミスだとか型宣言の忘れだとか、とても恥ずかしいです。


399 名前:デフォルトの名無しさん :03/12/27 02:36
>>398
もっと恥ずかしいのは自分でエラーメッセージを読まないことだな。

400 名前:デフォルトの名無しさん :03/12/27 11:26
クラスのメンバ変数につける
constとstaticって順番どっちでも意味同じなんですか?
static const int m_Value;

const static int m_Value;


401 名前:デフォルトの名無しさん :03/12/27 11:34
static const int
const static int
static int const
const int static
int static const
int const static
全部一緒

402 名前:デフォルトの名無しさん :03/12/27 12:12
全部一緒だけど、あんまり変な書き方すると読みにくい。

403 名前:デフォルトの名無しさん :03/12/27 12:51
static const 型名

で漏れは統一してる。

404 名前:デフォルトの名無しさん :03/12/27 13:38
int const staticで統一してる人とかいるのかな?
すげー読みにくい気がする


405 名前:デフォルトの名無しさん :03/12/27 14:49
つかバラバラなのが最悪

406 名前:デフォルトの名無しさん :03/12/27 15:59
スコープに関する修飾詞はなんとなく前のほうにもっていくのが普通だね

407 名前:デフォルトの名無しさん :03/12/27 16:42
記憶クラスは型じゃないから型を読むのを
妨害しないように(つまり左)に書いてる
constは本音ではint constと書きたいが
漏れの周りがconst intなので協調してる

408 名前:デフォルトの名無しさん :03/12/27 16:44
漏れはclass derived : public virtual baseって書いてるけど
文句ある人の批判を聞いてみたい

409 名前:デフォルトの名無しさん :03/12/27 16:53
つーか仮想継承しないし。

410 名前:デフォルトの名無しさん :03/12/27 16:57
>>409
まったくだ(笑)

411 名前:デフォルトの名無しさん :03/12/27 17:08
基本的な質問でスマソですが、

class foo {
public:
  foo () throw(bar);
  class bar;
};

class foo::bar : public exception {
  int x;
};

以上のコードをコンパイラに通す方法は
どうやればいいんでしょうか?
bar の前に throw (bar) があるので、事前に
bar を宣言しないといけないのですが、

冒頭に
class foo;
class foo::bar;
とやってみたり、

class foo {
  class bar;
};
とやってみたりしましたが、いずれもエラーが
でてしまいます。

412 名前:デフォルトの名無しさん :03/12/27 17:12
>>411
class foo {
public:
  class bar : public exception {
    int x;
  };
  foo () throw(bar);
};



413 名前:デフォルトの名無しさん :03/12/27 17:13
>>412
もちろん、そういう解決法はあるのですが、
なんとか>>411の順番で通す方法は
ないものかと思いまして・・・。

414 名前:デフォルトの名無しさん :03/12/27 17:14
throw(class bar)

415 名前:デフォルトの名無しさん :03/12/27 17:14
>>413
>>412こそが普通だが。

class foo {
public:
  class bar; // 宣言を先に
  foo () throw(bar);
};
これじゃ通らないん?

416 名前:デフォルトの名無しさん :03/12/27 17:23
>>414
これで通りました!
ありがとうございます。

>>415
なんとなく、例外で投げられるクラスをクラス宣言の
一番下にもっていきたいなと思いまして。あんまり
一般的じゃないんですかね。

417 名前:デフォルトの名無しさん :03/12/27 17:27
>>416
ちなみに>>414>>415の2行をひとつにまとめたものね。
いきなり識別子を出してもそれが何であるかコンパイラには分からないので
まずそれがclass名であるということだけを先に宣言しておく。

418 名前:デフォルトの名無しさん :03/12/27 17:34
>>409
ライブラリの仕様で決まってたりする

# 捨てろとか言うと恥かくぞ
# 笑う人たちはレスしそうにないが

419 名前:デフォルトの名無しさん :03/12/27 17:39
>>418
設計のおかしいライブラリを使わざるを得ない状態ってやつか。

420 名前:デフォルトの名無しさん :03/12/27 17:51
つまり、文句が出てくるほど使われていはない、ってことさ。
400だって、volatileとかsignedを何処に挟むか聞いてないだろ。

421 名前:デフォルトの名無しさん :03/12/27 19:03
少なくともおまいらの知らない分野らしいことはよくわかったyo
最近は富豪的プログラミングがトレンドなんだろ、どーせ

422 名前:デフォルトの名無しさん :03/12/27 19:27
static const volatile unsigned short int ax;

423 名前:デフォルトの名無しさん :03/12/27 19:32
>>421ほど'yo'の似合わない文体は初めて見た。

424 名前:デフォルトの名無しさん :03/12/27 19:52
extern static const volatile unsigned long long int val = ULLONG_MAX;

・C++にlong longないけどな……
・externとstaticって同居できたっけ?

425 名前:デフォルトの名無しさん :03/12/27 19:59
const volatile は普通 extern だと思ったが
インラインアセンブラでどうにでもなりそうだし
どちらにしろ使ったこと無いので
どうでもいいや。

426 名前:デフォルトの名無しさん :03/12/27 21:00
さらにresister修飾子も付け加えられる事に気づいたが、さらにどうでもいいや

427 名前:デフォルトの名無しさん :03/12/27 21:08
register/static/externはそれぞれ排反しないかな?
意味がないだけでつけられるのか、つけてはいけなかったか覚えてないけど。

428 名前:デフォルトの名無しさん :03/12/27 22:24
>>419
標準ライブラリだと iostream とか。

まぁ、使わないけどな。

429 名前:デフォルトの名無しさん :03/12/28 01:25
>>428
漏れ使いまくってる。特にstringstream系とか。
別に使う分には設計おかしいとは思わないけどなあ。
派生しようとすると大変かもしれんけど。

430 名前:デフォルトの名無しさん :03/12/28 02:08
>>429
stream 系は設計おかしいよ。

431 名前:デフォルトの名無しさん :03/12/28 02:16
>>430
どういう点が?

432 名前:デフォルトの名無しさん :03/12/28 02:41
operator>>/<<のことだろ

433 名前:デフォルトの名無しさん :03/12/28 03:14
>>431
菱形継承してる点も、今から見るとちょっと…。

434 名前:デフォルトの名無しさん :03/12/28 06:58
正直、10年C++やってるがiosよくわからない


435 名前:デフォルトの名無しさん :03/12/28 11:57
使ってる手段だけで解ったような決まり文句を言い出す青二才とは接点がない

436 名前:デフォルトの名無しさん :03/12/28 15:42
>>428 何使ってるの?

437 名前:デフォルトの名無しさん :03/12/29 12:54
>>432
いまや >>/<< は入出力演算子です。
整数型だけ、シフト演算するようにオーバーロードされているのです。

438 名前:デフォルトの名無しさん :03/12/29 14:21
>>437
へ?std::basic_ostreamのテンプレートクラスのメンバ関数
じゃないの?

すなわち
 std::cout << 1 << std::endl;

 std::cout.operator<<<int, std::char_traits<int> >(1) << std::endl;
と同じ。

439 名前:マジレスにマジレス :03/12/29 15:43
>>438
ちょっと違う。
メンバ関数で実装されてるのは組込型に対してだけ。
それ以外はグローバル関数としてオーバーロードされている/されることになる。


440 名前:マ(ry :03/12/29 15:51
>>439
#include <cstdio>
struct Ore_stream
{
    Ore_stream &operator<<(const char *str) {std::puts(str); return *this;}
};

441 名前:デフォルトの名無しさん :03/12/29 19:07
一瞬OLE_streamかと思た

442 名前:デフォルトの名無しさん :03/12/29 19:41
>>437
ああそういう事か。シフト演算子の左辺に整数型がある時は
シフトするという意味ね。
>>439
クラスのメンバは大抵privateにしておくので、入出力演算子
は大抵friendで宣言しておいて後からグローバルで定義す
るよね。

443 名前:デフォルトの名無しさん :03/12/29 19:43
std::cout.operator<<<int, std::char_traits<int> >(1).operator<<(std::endl);
↑しかし読みにくいねえ。こんな風に書かなくて良くて良かったYO。

444 名前:デフォルトの名無しさん :03/12/29 21:37
>>442
>大抵friendで宣言しておいて

んなことしねーよ
それじゃprivateになってないだろ
後から定義したグローバル関数に依存されちまう

445 名前:デフォルトの名無しさん :03/12/30 05:00
>>444
そしたらどうやって書くの?クラスのメンバ関数で<<演算子の
定義はできないよ。thisはクラスオブジェクトを指すのであって、
std::ostreamは指してくれないよ。

ダメな例:

class Cls {
 int x;
public:
 std::ostream& operator<<(std::ostream& os, const Cls &c) const {
  os << c.x;
  return os;
 }
};

class Cls {
 int x;
public:
 std::ostream& operator<<(std::ostream& os) const {
  os << this->x;
  return os;
 }
};

446 名前:デフォルトの名無しさん :03/12/30 05:01
良い例:

class Cls {
 int x;
public:
 friend std::ostream& operator<<(std::ostream& os, const Cls& c);
 Cls() : x(0) {}
};

std::ostream& operator<<(std::ostream& os, const Cls& c)
{
 os << c.x;
 return os;
}

これ以外に定義の仕方知らないんだが。他に良い方法が
あったら教えて欲しい。

447 名前:デフォルトの名無しさん :03/12/30 08:16
>>445
それoperator<<よりdebugprintていう名前のほうがいいんじゃないの

俺は
std::ostream& operator<<(std::ostream& os, const Cls& c)
{
 os << c.public_get_value();
 return os;
}
例えばClsがstd::stringなら
std::ostream& operator<<(std::ostream& os, const std::string& s)
{
 os << s.c_str();
 return os;
}

448 名前:デフォルトの名無しさん :03/12/30 12:31
>>447
なるほど、サンクス。という事はfriendはわざわざキーワードの
使い方を説明するために使って見せただけなのか。

そしたら

std::cout << c;

と書く代わりに

std::cout << c.public_get_value();

と書いても同じだね。friendはカプセル化手法に穴を開けるもので
ある事は知ってたけど、うまく使えば入出力関数を作らなくて済む
ので便利なものだと思っていた。

449 名前:デフォルトの名無しさん :03/12/30 12:33
>>447
クラスの内部メンバの情報が public で見られるとは限らないから
たとえ出力演算でも friend 宣言がいることもあるんじゃない?
設計がデバッグ出力でなければ public な情報だけ見られりゃ十分ってのは理想じゃないかなあ……。

でも>>444のthis云々は意味がよくわからん。
もしかしてクラス内でグローバル関数を宣言する目的(だけ)で friend 宣言してるってこと?
ちなみに俺なら friend で宣言した場合にもグローバル関数ならアクセサメソッドを通すようにするが。

450 名前:デフォルトの名無しさん :03/12/30 12:44
上書きがいやなら名前空間をしっかり管理しろと

451 名前:デフォルトの名無しさん :03/12/30 12:47
少々話は逸れるけれど、
そのアクセサ public_get_value() も出力演算のためだけに追加したものなら
それのアクセサ自体を private/protected において出力演算を friend 宣言すべきかな?

本来出力以外では不要なアクセサが他に公開されるのは本末転倒な気がする。
しかし、こうしてしまうと別のストリームに対する入出力を追加したいときに
クラスの定義からいじらないけなくなる。

設計がしっかりしてりゃんなことないって言われりゃごもっともなんだが。

452 名前:デフォルトの名無しさん :03/12/30 17:09
プログラムの質問じゃないのですが申し訳ない。
VC++でビルドをかけるとよくリンクの途中で止まってしまいビルドの中止を選んでも止まりません。
しかたなくタスクマネージャから終了かけるのですが、これってなんとかならないでしょうか?

453 名前:デフォルトの名無しさん :03/12/30 17:33
>>452
ハードが腐ってるんじゃないの? リンク処理は CPU, メモリに負荷を掛けるから
普段ギリギリの状態で動いているマシンだと死にやすい。

454 名前:452 :03/12/30 17:42
>>453
そ、そうなんですか・・・?
結構新しいマシンなんですが…
部品変えるべきですか?

455 名前:デフォルトの名無しさん :03/12/30 17:46
ハードディスクがいっぱいいっぱいとか。

456 名前:452 :03/12/30 17:52
30G空いてます。

スペック
CPU:P4 2.8C
メモリ:DDR400 512M*2
HDD C:40G D:80G

メモリ*2がノーブランドなんですがこいつですかね?

457 名前:デフォルトの名無しさん :03/12/30 17:54
メモリに負荷のかかる別のアプリ(自分で作ってもいい)を使っても
止まるようなことがあればメモリのせいかも。

458 名前:デフォルトの名無しさん :03/12/30 17:55
>>456
memchk86は?

459 名前:デフォルトの名無しさん :03/12/30 18:45
>>452
俺もクラスのメンバ増やしたり減らしたりしたときになることがある。vc6。

460 名前:貧乏紙 :03/12/30 19:58
>>452
OSがwin98orMeじゃない?

461 名前:452 :03/12/30 20:17
OSは2000proです。みなさんたくさんのレスありがとうございます。
警告がでる場合などに止まりやすいみたいです。

462 名前:デフォルトの名無しさん :03/12/30 20:31
int a;
double b,c;

c = (double)a * b;

こういうことをする意味はあるのでしょうか?
実を言うとc#でやるんですが、これはコンパイラによって話が別なんでしょうか?

463 名前:デフォルトの名無しさん :03/12/30 20:35
462です。

c = a * b;
と比べてという意味です。
こうした場合精度は失われるのでしょうか?

464 名前:デフォルトの名無しさん :03/12/30 20:40
>>462
数値演算はオペランドの中でもっとも”大きな”型に自動的に格上げされる。
これは言語の規定であって環境依存はしない(C#はしらんがC/C++ではそう)。

その例の場合は a が自動的に double に格上げされるんで
明示的にキャストする必要はないから安心し。

double a = (double)5 / 3 * 0.5
みたいな場合は int 同士の除算が先にあるんで必要だけど。


465 名前:デフォルトの名無しさん :03/12/30 21:49
>>464
遅レス申し訳ないです。

自分には大変勉強になりました。
下らない質問に回答頂きありがとうございました。

466 名前:デフォルトの名無しさん :03/12/30 22:42
教えてください。
CStringなどのクラスインスタンスをメンバに持つクラスを、
恐らく静的に作成したりZeroMemoryなどで初期化したりすると、
使用したときにエラーを起こしてしまいます。

vfptrが0に初期化されたからだと思いますが、
このvfptrを元に設定し直すと言う事はできるのでしょうか?

またはクラスメンバにそういったクラスインスタンスを持たせることはまずいのでしょうか?
動的に作成すれば問題はありませんが、クラスインスタンスは動的に作成するものなんでしょうか?


解決方法、というか一般的に取られている方法などがあれば教えてください。

467 名前:デフォルトの名無しさん :03/12/30 22:52
具体的な作成プロセスがようわからんが、
インスタンスの初期化はコンストラクタで行うのが基本だ。
ZeroMemoryなんか論外。クラスのポインタ型メンバが 0 (NULL) にセットされりゃそりゃ落ちる。


468 名前:466 :03/12/30 23:02
>>467
レスありがとうございます。
よく見たらコンストラクタでZeroMemory(this, sizeof *this);なんてやってました……。
データだけのインスタンスの時は確かに正常だったわけですが、
これで関数呼んだら確かに落ちますよね……。


個人的に疑問に思ったのですが、vfptrを再設定する方法というのはあるのでしょうか?
単純に他のインスタンスからコピーしてもダメみたいですが……。

469 名前:ヽ(´ー`)ノ :03/12/30 23:11
>>466
vfptr 弄ったりしちゃダメ。
なんで ZeroMemory なんか使いたいの?やりたい事言った方がいいと思う。
多分アプローチの仕方が間違ってるんじゃないかな。

470 名前:デフォルトの名無しさん :03/12/30 23:13
vfptrは直接いじれるものでもいじるものでもない。

そういう場合は
Class BaseFunctionImpl() {
...
virtual BaseFunctionImpl* Clone() = 0;
virtual ~BaseFunctionImpl() = 0;
};

Class FunctionImplA : public BaseFunctionImpl() {
...
};

Class ClassA {
...
BaseFunctionImpl* fptr;
...
};

のように動的に割り当てたい関数だけを集約した抽象基底クラスへのポインタを
メンバとして持つようにする。


471 名前:デフォルトの名無しさん :03/12/30 23:14
ヘッダーファイルで
using namespace std;
と書くのはよくないと思うのですが、普通は
どのようにするのでしょうか?

やはり、宣言は全てstd::をつけたほうが良いのでしょうか?


472 名前:デフォルトの名無しさん :03/12/30 23:16
>>471
まあ、普通に全て std:: 付ける。

473 名前:デフォルトの名無しさん :03/12/30 23:17
>>468
消す前にデストラクタを明示的に呼び出して、
ゼロクリア後に配置構文newを使えば大丈夫...つか、そんな事始めからするな。

474 名前:デフォルトの名無しさん :03/12/30 23:20
>>471
inline 関数内限定でなら using namespace std; することもある。

475 名前:デフォルトの名無しさん :03/12/30 23:23
>>471
インスタンスの型宣言に関してはローカルに typedef してエイリアスを作ってしまう。
関数に関しては、inline でない限りヘッダには書かないはずだし。

476 名前:デフォルトの名無しさん :03/12/30 23:24
質問です。

固定長ファイルを読み込むときって、
皆さん、どんな風なプログラム書かれています?

31.412.2 2.132.1
23.1

↑みたいなファイルです。
(上の例だと5つとも全部小数第1位までの3桁の実数)

477 名前:デフォルトの名無しさん :03/12/30 23:26
つーか namespace はオープンだからそこでグローバルに using したらやばいけど
関数内部やクラス内部のローカルスコープは外から参照できないんで使ってもそれほど実害はない。


478 名前:466 :03/12/30 23:29
>>470
そんな大層な事をするクラスでもなかったもので……

>>469,473
いえ、クラスのメンバが多いので初期化をラクしたかったというか。
ただのデータホルダとして、構造体の代わりとして使っていたものに関数を追加したら
そうなってしまって。

あの、新たな疑問が浮かんできたんですが、
struct内で関数を宣言した場合どうなのるかな?と試してみたら、
structではZeroMemoryしても関数は呼び出されるのですね。

structとclassの違いを漠然と覚えていましたが、
よく分からなくなってしまいました……。
クラスのメンバメソッドはvfptrからアクセスするわけですが、
structの関数はどういう形でよびだされているのでしょうか?


479 名前:471 :03/12/30 23:33
>>472, 474, 475
レスありがとうございます。
参考にさせていただきます。

480 名前:デフォルトの名無しさん :03/12/30 23:33
classとstructは、デフォルトのアクセス修飾子が異なるだけで、全く同じもの。

481 名前:デフォルトの名無しさん :03/12/30 23:35
>>478
正直君はvfptrとかを使うレベルに達していないようだが理解は正確か? とてもそうは思えない。
virtual でないメンバ関数はすべてコンパイル時に割り当てられる。インスタンスにその後は残らない。
メンバ関数を追加してsizeofの値を確かめて見ればわかる。

C++におけるstruct と class の違いは
指定なしのメンバのアクセス指定子と継承方法が public か private かくらい。

きちんとした違いは内部のデータ構造に現れる。POD = plain old data でぐぐってみろ。

482 名前:ヽ(´ー`)ノ :03/12/30 23:48
> いえ、クラスのメンバが多いので初期化をラクしたかったというか。
> ただのデータホルダとして、構造体の代わりとして使っていたものに関数を追加したら
> そうなってしまって。
それはイクナイ。

クラスのメンバは面倒でも一つ一つ初期化すべきだよ。
でないと、他の人がコード読んだ時に、何やってるかを一発で理解できないじゃん。


483 名前:デフォルトの名無しさん :03/12/30 23:56
問題はいろいろあるが、
この場合の一番の問題は CString 型メンバを勝手にサイズ分ゼロで初期化したことだろ。
内部構造がわからんクラスインスタンスに対し(わかっていても)
そんな初期化方法は邪悪以外の何者でもない。

>>467でも書いたが原因はおそらく内部文字列へのポインタが NULL になって実行時エラーになってる。
仮想関数を用いていないようなのに vfptr 云々はどこから出てきたんだ?

484 名前:デフォルトの名無しさん :03/12/31 00:04
struct T{
POD1 p1;int i,j,k;POD2 pe;
virtual ~T(){}
T(){ ZeroMemory( &p1, (char*)&pe - (char*)&p1 + sizeof(pe) );}
};

485 名前:デフォルトの名無しさん :03/12/31 00:17
意味もわからずメンバをvirtualにしたり、仮想デストラクタをつけたりしてる場合もあるが..
この場合は、vtblは関係ない気がする。

ZeroMemoryやmemcpy, memsetといったCでよくやるメモリ操作はなるべく
使わないようにしなさいな。
C++のカプセル化を破壊するか、その後の拡張を阻害する要因になりがちだ。

Cあがりだと、明示的なキャストを使い続けるケースが多いけど、あれもどうにか
やめさせられんかねえ...


486 名前:デフォルトの名無しさん :03/12/31 00:47
>Cあがりだと、明示的なキャストを使い続けるケースが多いけど、あれもどうにか
>やめさせられんかねえ...

_| ̄|○ スマナイ…

487 名前:デフォルトの名無しさん :03/12/31 01:53
Cの文法を理解したヤシがC++を始めるにあたり良い入門書ってないでしょうか?
易しすぎず、難しすぎずぐらいのもの。
できればCとの記述の違いも書いてくれていればなお良いんですが・・・。

488 名前:デフォルトの名無しさん :03/12/31 02:02
>>487
http://pc2.2ch.net/test/read.cgi/tech/1072184936/
しかもその手の質問はさんざん既出

489 名前:デフォルトの名無しさん :03/12/31 02:02
「CプログラマのためのC++入門」つー、まんまな本があるが俺はおすすめしない。
標準ライブラリに関する記述が完全に時代遅れなので。
つか、ISO標準化から5年も経ってるのに改訂されてない時点で捨てていい。

ある程度知識があるならいきなり「プログラミング言語C++」から入ってもいいと思うけどな。

490 名前:デフォルトの名無しさん :03/12/31 09:29
>>487
このスレをpart1から読めばただでそこらに売っている本より理解を深める事が出来る
もしそれが嫌ならば自分で買って確かめるしかない。ちなみに日本人原作で良い本には
なかなかめぐり合えないでしょう。
そして、入門書なんてどの本も似たり寄ったり肝心なことが抜けてる

491 名前:デフォルトの名無しさん :03/12/31 10:08
まだ入門書なんて探してるあたり
Cの文法が理解できたと言っているのを
あまり買いかぶらない方がよさそうだぜ

492 名前:デフォルトの名無しさん :03/12/31 10:56
一度JavaをとlispあたりをかじってからC++に戻ってくれば?

493 名前:デフォルトの名無しさん :03/12/31 12:52
>>481の言うとおり、>>466はvfptr云々のレベルではないね。
特に、CStringに対してZeroMemoryで初期化しているあたりを見ると
1)C++特有の約束事

2)オブジェクト指向的な考え方
のどちらも多分ほとんど身についてない。

1)に関してだと、たとえば
「内部で動的にメモリを確保するメンバがいたら、コピーコンストラクタ
と代入演算子はかならず自前で用意する」
などなどの基本事項は大丈夫?

2)に関して言えば、メンバに利用しているクラスなり構造体なりの
内部構造が変わったとしたら、ZeroMemoryしていいかどうかなんて
誰も判断できなくなる。だから、>>482の言うとおり、素直に初期化
を書くべき。Cでゴリゴリ書いてるんじゃないんだから。

上のことがちょっとでも理解できてないのなら、たとえCの文法がわかっていても
(というか、文法がわかっているのとプログラムが書けるということは本当は
全然別のことなんだけど)、>>487で書いているような無理はせず、きちんと
基本が書いてあるC++の本を読むべきと思う。正直、応用段階ではないよ。
それを読んだら、あとはEffective C++くらいは最低理解しておく。


494 名前:デフォルトの名無しさん :03/12/31 13:11
POD struct なら ZeroMemory することはよくあるけどね。

495 名前:デフォルトの名無しさん :03/12/31 13:16
>>494
漏れは滅多にしない。 代わりに

  PODstruct hoge = { 0 };

を多用する。てか、なんで Win32API を前提に話を進めてるんだ?
使うなら memset だろ。

496 名前:デフォルトの名無しさん :03/12/31 13:28
>>495
そうだな。memset だ。
ポインタあるときは使わない方がいいけど。

コンパイラ(と警告レベル)によっては
PODstruct hoge = { 0 };
で警告出すこともある。

497 名前:デフォルトの名無しさん :03/12/31 13:28
ところで>>476よ。
そろそろそのファイルのフォーマットを明らかにしてくれんかね。
まず空白文字による区切りがあるのかないのか
整数部分の桁数はいくつなのか
最低その2つがわからんと「固定長」の定義がわからん。

#科学表記による入力はどうだとか
#小数点は"."のみでなく","も含むのかとかもあるけど

どちらにせよそれだけのために自前の入力ストリームを作る気はしないな。
やってCの scanf 系列を使うかだ。
標準の istream に不満があるならそれも書いてくれ。

498 名前:デフォルトの名無しさん :03/12/31 14:37
>>481
きちんとした違いとは何ですか
>>480氏の答えと時間差で遅れたのですか?

499 名前:デフォルトの名無しさん :03/12/31 15:26
>>497
多分>>476は4文字づつ取り出して処理するって話かも。
まあ、いまどきそんなフォーマット扱うほうが珍しいとは思うが。

500 名前:デフォルトの名無しさん :03/12/31 15:28
>>498
いや、問題はclassとstructの違いではなく
PODとそれ以外だ、という話なんでは?

で、それ以外(=classまたはstruct)だが
仮想関数が含まれるかどうかで違いはあるにしろ
現在ないからといってそれに依存するとあとで足したときに死ぬので
PODでないもの相手のときは常にmemsetとかで塗りつぶすのは厳禁と。


■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.