Windows 環境では幾つかの型(少なくないと思いますが)を typedef で定義されています。
例えば SNMP 類だと
typedef HANDLE HSNMP_ENTITY;
typedef HANDLE HSNMP_CONTEXT;
等。
こういった HSNMP_ENTITY や HSNMP_CONTEXT を扱うAPI群を幾つかのクラス化する場合、
基本処理を1つのテンプレートクラスで書こうとして、代入オペレータ
operator=(const TYPE& h);
を書いても TYPE を見分けてくれません(HSNMP_ENTITYとHSNMP_CONTEXTとを)。
typedef が弱い型付けである為、止む無いと考え、各末端のテンプレートクラスの派生クラス毎に書く事で妥協しました。
うまい手があればご教授願います。
No.2ベストアンサー
- 回答日時:
こんな感じにできませんか?
template <class Traits>
class Goo : public GooBase, public Traits
{
public:
Goo& operator=(const Goo& other);
...
};
typedef Goo<traits_1> Goo1;
typedef Goo<traits_2> Goo2;
...
typedef Goo<traits_1000> Goo1000;
全ての型に共通の部分をGooBaseで定義し、それぞれに固有のメンバ関数をTraitsとして提供すれば、実現できそうな気がします。
# TraitsよりPolicyといった方がいいかも...
ご回答有難うございます。
掲示頂いたスタイルを参考に見直したいと思います。
なお、代入演算子については好ましくない指摘もありましたし、必要かどうか見極めたいと思います。
貴重な助言を頂き、有難うございました。
No.4
- 回答日時:
HGOO_1 h1 = ::CreateGoo1(...);
HGOO_2 h2 = ::CreateGoo2(...);
Goo1 goo1;
Goo2 goo2; // ← [訂正]こぴぺミス…orz
goo1 = h1; // ←こういう記述を許可すると
goo1 = h2; // この誤認識を禁止できない
goo1 = goo2; // ←これをコンパイルエラーにはできるので、
goo1 = Goo1(h1); // explicitにこうする。
No.3
- 回答日時:
「生ハンドルからの代入演算子」を作りたい?
それは、この場合1~1000のtypedefの実体がすべてHANDLE(言語的にはvoid*)なので、自動の型類推はできません。
> typedef が弱い型付けである為、止む無いと考え、
> 各末端のテンプレートクラスの派生クラス毎に書く事で妥協しました。
最終的に何らかの妥協は必要と思われます。
Goo1のoperator=に生ハンドルを渡せば、ソース上でHGOO_1であろうとHGOO_2であろうと同じHGOO_1のものが呼ばれます。
なので、このような代入演算子は書かないのが安全。
生ハンドルはコンストラクタのみで渡すようにし、コンストラクタは引数を複数にするか、explicit指定をつける。
手軽な変換を許すと代入で暗黙変換されて危険な典型だと思います。
コンストラクタのtraitsは結局プログラマが自分で指定せざるを得ない。
HGOO_1 h1 = ::CreateGoo1(...);
HGOO_2 h2 = ::CreateGoo2(...);
Goo1 goo1;
Goo1 goo2;
goo1 = h1; // ←こういう記述を許可すると
goo1 = h2; // この誤認識を禁止できない
goo1 = goo2; // ←これをコンパイルエラーにはできるので、
goo1 = Goo1(h1); // explicitにこうする。
実装の方向性としては#2さんの方法でいいと思いますが、元のコードの延長だとたとえばこんな感じでしょうか。
# コンパイルはしてません。VC6はもうMSのサポート切れですし。
// Type:templateはHGOO_1もHGOO_2も区別しないので渡しても意味がないが、
// (STRICTならHANDLE以外の)HDC等を渡すことはできるはず…
template <typename Traits, typename Type=HANDLE>
struct GooBase {
typedef Type Type_type;
...
};
struct Goo1 : public GooBase<Goo1> {
explicit Goo1(Type_type handle);
operator=(const Goo1& h);
}
// traits(=識別用の型)が本当に単なるマーカなら、typelistで多少はきれいになるのかも。
ちなみに、VC6だとtemplate実装が甘くて、メンバ関数の特殊化とか部分特殊化に制限/バグがあるので留意が必要です。
理想的なコードを回答頂き、有難うございます。
スッキリした気になりました。
>このような代入演算子は書かないのが安全。
そうでした... 見直して廃止できないか検討します。
>typelistで多少はきれいになるのかも。
最近、本でその存在を知ったばかりでして...
これを機に応用したいと思います。
No.1
- 回答日時:
やりたいことがよく分からないのですが、HSNMP_ENTITYとHSNMP_CONTEXTで、多重定義かテンプレートの特殊化をやり
たいということでしょうか?この回答への補足
ご返答有難うございます。
作戦としては、以下のような1000個のハンドルが有るとし、
typedef HANDLE HGOO_1;
typedef HANDLE HGOO_2;
...
typedef HANDLE HGOO_1000;
これらに固有の関数群をクラスでラッパしたい考えです。
それらを Goo1~Goo1000 とします。
ここで各クラス化に於いて類似コードを基本クラスに置いた方が良いと考え、それをテンプレートクラスとしました。
template <class TYPE, class 識別用の型>
class GooBase {...};
//
class Goo1 : public GooBase<HGOO_1, 識別用の型> {
operator=(const HGOO_1& h); // <---
...
};
ここで Goo1~Goo1000 にある代入オペレータ
operator=(const TYPE& h);
を GooBase へ置こうとしても機能してくれない点が難点です。
なお、コンパイラは VC6 です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- 大学・短大 レポートの書き方が分かりません 4 2022/09/18 13:30
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- 電気工事士 【大型発電機】ハツリ作業等に使われるトラックの荷台に積まれている四角い大型発電機は2 1 2023/04/24 19:22
- 相続・贈与 亡くなった父の土地名義変更について 6 2023/02/13 23:28
- その他(教育・科学・学問) 大学期末試験における不合格処理はなるべく避けた方がいいですか。 3 2022/08/20 15:42
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/06 09:28
- モテる・モテたい 時間に余裕がある方!! 学生になったつもりで答えてください! 私のクラスには魅力的な男子がたくさんい 2 2022/10/05 22:14
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
範囲外の数値を代入したらエラ...
-
java.util.ArrayListクラスの継承
-
アップキャスト、ダウンキャス...
-
SwingでgetContentPaneのエラー...
-
ひとつのファイルにクラスは1つ?
-
C++/C#間での構造体の引き渡し...
-
クラス間でのデータ参照
-
Publicとは?
-
dllエクスポート時のdeclspec(d...
-
java-別クラスの変数の使い方を...
-
jarファイル内のクラスをインス...
-
ファクトリーパターンの適用の仕方
-
c++,ある関数のクラスから別の...
-
javac が実行できません。。
-
内部クラスのインスタンスを外...
-
リフレクション
-
関数内の変数に<summary>コメン...
-
エクセルVBAで、条件に一致する...
-
「タイプ初期化子が例外をスロ...
-
インスタンス参照でアクセスで...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
クラス間でのデータ参照
-
範囲外の数値を代入したらエラ...
-
関数内の変数に<summary>コメン...
-
c++,ある関数のクラスから別の...
-
C#にて別クラスの関数を使いたい
-
java-別クラスの変数の使い方を...
-
C++でfriendクラスにしているの...
-
a href="..." とServlet
-
親クラスから子クラスへアクセス。
-
構造 他のクラスの構造体を別...
-
Java リフレクションについて
-
import と extends について
-
C#でほかのファイルにある自作...
-
C#のクラスライブラリでメッセ...
-
Java
-
アップキャスト、ダウンキャス...
-
無名パッケージからのインポート
-
違うクラスからの変数の共有化
-
SwingでgetContentPaneのエラー...
-
ひとつのファイルにクラスは1つ?
おすすめ情報