[解決済み] C++で同じクラスに対して異なる型を定義する方法
質問
C++で、実装が同じで型が異なる複数の型を持ちたいと考えています。
私の質問を簡単な例で説明すると、私はリンゴ、オレンジ、バナナのクラスを持っていて、すべて同じ操作と同じ実装を持っています。私は、型安全性のおかげでエラーを回避したいので、それらに異なる型を持たせたいと思います。
class Apple {
int p;
public:
Apple (int p) : p(p) {}
int price () const {return p;}
}
class Banana {
int p;
public:
Banana (int p) : p(p) {}
int price () const {return p;}
}
class Orange ...
コードが重複しないように、ベースクラスのFruitを使用して、それを継承することができそうです。
class Fruit {
int p;
public:
Fruit (int p) : p(p) {}
int price () const {return p;}
}
class Apple: public Fruit {};
class Banana: public Fruit {};
class Orange: public Fruit {};
でもそうすると、コンストラクタが継承されないので、書き直さなければなりません。
同じクラスで異なる型を簡単に持てるような仕組み(typedef、テンプレート、継承...)はないのでしょうか?
どのように解決するのですか?
一般的なテクニックは、クラステンプレートを持つことで、テンプレートの引数が単にユニークなトークン(「タグ」)として機能し、ユニークな型となることです。
template <typename Tag>
class Fruit {
int p;
public:
Fruit(int p) : p(p) { }
int price() const { return p; }
};
using Apple = Fruit<struct AppleTag>;
using Banana = Fruit<struct BananaTag>;
タグクラスは定義する必要がないことに注意してください。 宣言 を宣言するだけで十分です。これは、タグが実際には を使用します。 タグがテンプレート内のどこかで実際に使われているからです。そして、型名を宣言することができます の内部で の中で型名を宣言できます (@Xeo に脱帽)。
は
using
の構文はC++11です。 C++03にこだわっている人は、代わりにこう書いてください。
typedef Fruit<struct AppleTag> Apple;
共通の機能が多くのコードを占める場合、残念ながら最終的な実行ファイルにかなり多くの重複したコードを導入することになります。これは、機能を実装する共通の基本クラスを持ち、それから派生する特殊化 (実際にインスタンス化する) を持つことで防ぐことができます。
残念ながら、そのためには、すべての継承できないメンバー (コンストラクター、代入...) を再実装する必要があり、それ自体小さなオーバーヘッドを追加することになります。ここでは、上記の例にそれを適用しています。
// Actual `Fruit` class remains unchanged, except for template declaration
template <typename Tag, typename = Tag>
class Fruit { /* unchanged */ };
template <typename T>
class Fruit<T, T> : public Fruit<T, void> {
public:
// Should work but doesn’t on my compiler:
//using Fruit<T, void>::Fruit;
Fruit(int p) : Fruit<T, void>(p) { }
};
using Apple = Fruit<struct AppleTag>;
using Banana = Fruit<struct BananaTag>;
関連
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件
-
[解決済み】'std::cout'への未定義の参照
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] Pythonで型をチェックする標準的な方法は何ですか?
-
[解決済み] ベースクラスのコンストラクタを呼び出す際のルールは?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 配列のベクトルを扱う正しい方法