No.2ベストアンサー
- 回答日時:
> 1.DataBaseのコンストラクタでlong id_にデータを代入しているところですが、{0,0,0,1}の並びだと16777216という値で格納されてしまい、create()のswitch文のgetId()id_を取り
> 出すと1に該当しなくなってしまいます。
ああ、すんません。パソコン(Intel系のプロセッサ)を使ってるんですね。
Intel系のプロセッサは、バイトの並びが反転するんです。long で 1 ならば、
{0,0,0,1} ではなく {1,0,0,0} としてみてください。
Webサイトを検索するのなら「エンディアン」とか「バイトオーダ」をキーワードに
して検索をしてみてください。
> 2.DataTypeA,Bのコンストラクタでid_をのぞいたデータを代入するわけですが、
> たくさんの異なった型が並んでいる場合、ポインタを使わずに簡単に代入できるテクニックなどってありますでしょうか?
テクニックというほどではないですが、それぞれの識別ID毎にデータの構造を記述した
構造体を宣言して、それを利用すると、ソースの読みやすさは向上します。
先の回答の DataTypeA のところだけをちょっと書き直してみます。
//------------------------------------------------------------------------
// TYPE 1
//
class DataTypeA : public DataBase {
public:
DataTypeA(char*);
~DataTypeA() {}
void print() const;
private:
short s1_, s2_;
struct DataTypeA_info {// このクラスでしか使わないんだから private で十分
short s1;
short s2;
};
};
DataTypeA::DataTypeA(char* buf) : DataBase(buf)
{
DataTypeA_info* p = (DataTypeA_info*)getBuf();
s1_ = p->s1;
s2_ = p->s2;
}
どうせ、構造体を記述するのであれば、その構造体をそのままメンバに持つという
選択もありますね。
//------------------------------------------------------------------------
// TYPE 1
//
class DataTypeA : public DataBase {
public:
DataTypeA(char*);
~DataTypeA() {}
void print() const;
private:
struct DataTypeA_info {// このクラスでしか使わないんだから private で十分
short s1;
short s2;
} info_;
};
DataTypeA::DataTypeA(char* buf) : DataBase(buf)
{
info_ = *(DataTypeA_info*)getBuf();
}
a-kumaさん、非常にありがとうございました。
自分ひとりでやっていて、なんとかプログラムはかけるものの、果たしてその書き方、考え方が合っているかなんて分からなくて非常に自分に自信がありませんでした。
このように、丁寧に専門家の人に見ていただくと、自分に自信が少し湧きます。
ありがとうございました。
No.1
- 回答日時:
> 今考えているのは、ベースクラスを作り、そのベースクラスを継承した各ID用の子クラスを作っているのですが、
基本的には、その方向で良いんじゃないでしょうか。識別IDによる伝文の種類や
その扱い方が変わることを考えて。
ちょっと長くなりますが、簡単に書いてみました。あくまでも、実装の仕方の
ひとつとして参考にして下さい。ポイントが幾つか。
・識別IDが伝文のどこにあるかは基底クラスで実装し、派生クラスには隠蔽
・データ部(識別ID以降)の扱いは、各派生クラスにお任せ
・識別IDによって、どの実装クラスが生成されるかを DataFactory クラスで実装し、利用者には隠蔽
・識別IDが想定外だと、例外を送出
ひとつのコードに一気に書いてますが、実際には、各クラス毎にヘッダファイルと
ソースファイルを作ります。
もし、扱う識別IDが増えた場合には、それを扱う派生クラスのヘッダファイルと
ソースファイルを作り、DataFactory の派生クラスを new する行を増やすだけ
で済みますね。
あ、ソースは、そのまま Cut & Paste できるように、漢字の空白を使って
いませんので、ブラウザでは、ちょっと読み難いですね。
#include <iostream.h>
//------------------------------------------------------------------------
// Data Base (にしても、クラス名が良くないね (^^;
//
class DataBase {
public:
DataBase() : buf_(NULL) {}
DataBase(char* buf) { buf_ = buf; id_ = *(long*)buf_; }
virtual ~DataBase() {}
virtual void print() const = 0;
long getId() const { return id_; }
protected:
char* getBuf() const { return buf_ + sizeof(long); }
private:
char* buf_;
long id_;
};
//------------------------------------------------------------------------
// TYPE 1
//
class DataTypeA : public DataBase {
public:
DataTypeA(char*);
~DataTypeA() {}
void print() const;
private:
short s1_, s2_;
};
DataTypeA::DataTypeA(char* buf) : DataBase(buf)
{
char* p = getBuf();
s1_ = *(short*)p;
p += sizeof(short);
s2_ = *(short*)p;
}
void DataTypeA::print() const
{
cout << "TYPE A : id = " << getId() << ", "
<< "s = " << s1_ << " " << s2_
<< endl;
}
//------------------------------------------------------------------------
// TYPE 2
//
class DataTypeB : public DataBase {
public:
DataTypeB(char*);
~DataTypeB() {}
void print() const;
private:
long i1_, i2_;
};
DataTypeB::DataTypeB(char* buf) : DataBase(buf)
{
char* p = getBuf();
i1_ = *(long*)p;
p += sizeof(long);
i2_ = *(long*)p;
}
void DataTypeB::print() const
{
cout << "TYPE B : id = " << getId() << ", "
<< "l = " << i1_ << " " << i2_
<< endl;
}
//------------------------------------------------------------------------
// Factory
//
class DataFactory {
public:
DataFactory() {}
~DataFactory() {}
DataBase* create(char*) const;
long getId(char* buf) const { return *(long*)buf; }
};
class BadIdException {
public:
BadIdException(long id) : id_(id) {}
private:
long id_;
friend ostream& operator<< (ostream&, BadIdException&);
};
ostream& operator<< (ostream& o, BadIdException& ex)
{
o << "ID = " << ex.id_;
return o;
}
DataBase* DataFactory::create(char* buf) const
{
DataBase* d;
switch (getId(buf)) {
case 1:
d = new DataTypeA(buf);
break;
case 2:
d = new DataTypeB(buf);
break;
default:
throw BadIdException(getId(buf));
}
return d;
}
//------------------------------------------------------------------------
// test code
//
int main(void)
{
char buf1[256] = { 0, 0, 0, 1, 0, 2, 0, 3};
char buf2[256] = { 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 19};
char buf3[256] = { 0, 0, 0, 3};
DataFactory factory;
DataBase* data;
try {
data = factory.create(buf1);
data->print();
data = factory.create(buf2);
data->print();
data = factory.create(buf3);
data->print();
} catch (BadIdException& ex) {
cout << "Exception ! (bad id). ex : " << ex << endl;
}
return 0;
}
ありがとうございました。
C++をはじめてまだ4ヶ月なので解読に時間がかかり、丸々一日考えさせてもらいました。
なるほど、このような感じで作ればよいのですね。すごく勉強になりました。
しかも、ものすごく丁寧にありがとうございます。助かりました。
二つほど教えてほしいです。
1.DataBaseのコンストラクタでlong id_にデータを代入しているところですが、{0,0,0,1}の並びだと16777216という値で格納されてしまい、create()のswitch文のgetId()id_を取り出すと1に該当しなくなってしまいます。
{0,0,0,1}のデータの並びでlongに1を代入するにはどうすればよいのでしょうか?
あちこちのWebサイトを探してみましたが説明が載っていません。
開発環境はWindows95なのですがなにか関係があるのでしょうか?
2.DataTypeA,Bのコンストラクタでid_をのぞいたデータを代入するわけですが、
たくさんの異なった型が並んでいる場合、ポインタを使わずに簡単に代入できるテクニックなどってありますでしょうか?
すいませんがご教授願います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelで全クラスのランキング表を作成したい 4 2022/05/24 15:28
- Excel(エクセル) 別シートに毎回異なるデータをコピーする 7 2022/06/24 09:02
- 中学校 娘のクラスの学級通信に個人情報が掲載されていて、非常に不快です。 7 2022/04/22 18:02
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- Visual Basic(VBA) vbaのvlookup関数エラー原因を教えていただけないでしょうか。 3 2022/04/25 16:16
- C言語・C++・C# 【C++】IDirect3DSurfaceのディープコピーは可能ですか? 1 2022/07/06 02:47
- Access(アクセス) access レポート 請求書について 2 2022/07/04 22:52
- Excel(エクセル) VBA : スクレイピングできない 4 2023/05/12 22:26
- その他(データベース) pythonでsqlight勉強中、クエリー結果の利用法教えて下さい 1 2022/04/28 20:38
- Visual Basic(VBA) VB.netのコンテナークラスとはなんですか 2 2023/07/22 03:54
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
c++,ある関数のクラスから別の...
-
クラス間でのデータ参照
-
内部クラスのインスタンスを外...
-
Java リフレクションについて
-
リフレクション
-
Java
-
java-別クラスの変数の使い方を...
-
関数内の変数に<summary>コメン...
-
整数値を任意のオブジェクトを...
-
リレーションエンティティクラ...
-
RPGの主人公、町人、敵キャラの...
-
Javaアプリケーションについて
-
違うクラスからの変数の共有化
-
二つの変数の値を入れ替えるメ...
-
C# log4netの使い方
-
エクセルVBAで、条件に一致する...
-
3年間同じクラスになる確率
-
インスタンス参照でアクセスで...
-
ワイルドカード<?>と型パラメー...
-
「天声人語」をインターネット...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数内の変数に<summary>コメン...
-
クラス間でのデータ参照
-
c++,ある関数のクラスから別の...
-
範囲外の数値を代入したらエラ...
-
C#にて別クラスの関数を使いたい
-
C#でほかのファイルにある自作...
-
C++でfriendクラスにしているの...
-
java-別クラスの変数の使い方を...
-
親クラスから子クラスへアクセス。
-
構造 他のクラスの構造体を別...
-
ひとつのファイルにクラスは1つ?
-
Java
-
import と extends について
-
継承したクラス側のクラス名の取得
-
SwingでgetContentPaneのエラー...
-
Java リフレクションについて
-
C#のクラスライブラリでメッセ...
-
アップキャスト、ダウンキャス...
-
C# インターフェイスの実装
-
visual studioのデザイナ画面で...
おすすめ情報