組み込みのC++データ型を独自のクラスにカプセル化する場合、どのような欠点(パフォーマンスやその他の欠点)が発生するのかを議論することはありません。たとえば、JavaやC#と同様に、intデータ型はIntという独自のクラスを持ち、インライン演算子でオーバーロードします。シングル、ダブル、ロングなどと同じ基本データ型をクラスにカプセル化する
答えて
利点はありません。あなたは、同じ行動やパフォーマンスを達成することはできません。
欠点:
- パフォーマンスはビルトインタイプよりも速くなることはありません。あなたが得られる最高のものは、すべてが組み込みの型コードにインライン展開されるクラスですが、そのポイントは何ですか?
- 、このような事業者が
- 非自明なコンストラクタ(必ずしもC++ 11で) を(主に鋳造)と同様に
- 仮想呼び出しが
- オーバーヘッド持っていないために、より多くのコードは同じ動作を実現することはできません多く、
- テンプレートパラメータなどのC++機能ではサポートされていません
- 混乱します。誰もこれをしません。
あなたは、単に整数または実数で十分だろうというとき、多くの種類のMathクラスをオーバーロードしたくない場合に有用である可能性があります。
あなたの頭にJavaが残っています。
C++テンプレートアプローチを取ります。
template<typename A_type, typename B_type>
auto math_operation(A_type a, B_type b) -> decltype(a + b * 2) {
return a + b * 2;
}
今、あなたは正しい演算子をサポートしている任意のタイプで動作機能を持っています。これはビルトインタイプ、およびInt128
などのクラスで機能します。
「あなたはJavaがあなたの頭に詰まっています。」 - それを出す方法があるのだろうか? :) –
エミュレートできない動作を詳しく説明できますか? –
実際にはC#が頭に突き刺さって、Javaの頭がMicrosoftの頭にぶつかった.-P – Dave
クラリティは苦しみますが、それはほとんどの場合です。
スマートコンパイラを使用している場合は、単にint
をラップし、操作を変更しないクラスは完全にインライン展開される可能性があります。コンストラクタを明示的に定義しないと、void f(OurVerySpecialInt i)
にはf(15)
と書くこともできます。しかし、もしあれば、あなたの非常に特別な機能を既存の機能に渡すのは難しいでしょう。
クラスだけでなく、クラス階層を意味する場合は、状況は非常に異なります。あなたはNumeric
を抽象基本クラスとし、それに派生するのはInt
とDouble
にしますか?その場合は、再検討してください。かなり遅いコードで終わる可能性が高いだけでなく、これを一般的かつ正気にする方法は実際にはありません。
operator+
をオーバーロードするクラスNumeric
を考えてみましょう。演算子が非メンバでなければならず、次に仮想ではありません。したがって、仮想メンバ関数Numeric
を呼び出す必要があります。しかし、どちら?Double() + Double()
はDouble
を返しますか? Double() + Int()
はどうですか? Double() + Rational()
はどうですか?最初の2つのケースでは、「Double
」と言うこともできますが、最後のケースでは有効ではありません。Double
が64ビットで、Rational
が2つの32ビット整数の商である場合、 (正の無限大と0.3などの)他の値で表現できない値があります。
それに加えて、あなたの機能は、ごくわずかしか約束できません。 Int32 i = 250; i += 250;
の後のiの値は何ですか?私はそれが500
だと仮定します。 Int8 = 250; Int8 += 250;
についてはどうですか? Numeric* p = new Int8(250); *p += 250;
はどうですか?あなたは魔法のように*p
を大きくすることはできないので、それをエラーにするか、オーバーフローさせてください。基本的にはp
がNumeric*
の場合、*p += 50000;
が何をするかわからない:*p += 5.3
を実行したときに精度が失われているかどうかを知ることはできません。
条件を厳密にしてこれらのエラーを修正すると、継承を必要としない何らかの種類のRational
またはBigInt
になります。すべての動作は厳密に(それが数学的実体であるべきであるように)厳密に指定されているので、それから派生しても何も変更できません。
これで十分ではない場合は、Numeric
クラスに仮想メソッドを指定した場合、すべての派生クラスにvtable(一般的な実装では)があることに注意してください。これは、クラスのすべてのインスタンスが通常よりも少しスペースを必要とすることを意味し、すべての数値を2倍にすると、実行していることによってパフォーマンスが大幅に低下する可能性があります。
- 1. EFを基本クラスにカプセル化する必要がありますか?
- 2. クラス外のデータをカプセル化する
- 3. int型、基本データ型
- 4. Luaのカプセル化クラス
- 5. クラスの列挙型の基本的な型を知るには?
- 6. JSONデータの基本クラス
- 7. 派生クラスを基本クラスにシリアル化する方法は?
- 8. クラスなしのPHPカプセル化?
- 9. Pythonクラスとカプセル化メソッド
- 10. Doughtは、基本的なデータ型
- 11. vtkデータ型と基本データ型の比較
- 12. は基本型
- 13. 基本クラスのプロパティのカスタムシリアル化
- 14. Objective-Cとデータのカプセル化
- 15. AutoMapper派生クラスを基本型コレクションのプロパティにマップします
- 16. 小さな抽象基本クラスでエンティティフレームワークの設定をカプセル化しないでください。
- 17. scala:型パラメータから基本クラスを継承する
- 18. Kotlin:基本クラスの派生ジェネリック型の値を構築する
- 19. 基本クラスのジェネリック型パラメータを取得する方法は?
- 20. クラスと基本クラス
- 21. テンプレートの基本クラスを基本クラスの引数として使用するクラス
- 22. 基本クラスの配列メンバ変数を基本クラスのコンストラクタから初期化するクラステンプレート値
- 23. 基本クラス別
- 24. アクティビティ基本クラス?
- 25. は、基本クラス
- 26. 基本クラス
- 27. BinDataで基本データ型を実装する
- 28. JSON.netで.net基本クラスにJSONを逆シリアル化します。
- 29. Serilogでイベントシリアル化の基本クラスのプロパティを省略する
- 30. 「基本データ型」と「組み込みデータ型」は同じ意味ですか?
私は反対の質問をすることはできますか?利点は何でしょうか? –
このような「透過」ラッパーと同様に、「演算子」のセマンティクスは失われる状況になります。 – Jon
1つの利点は、それらが基本クラスを継承できることです。 Int32:整数:数値:オブジェクトです。これは、単純にIntegerまたはRealで十分である場合に、多くのタイプのMathクラスに過負荷をかけたくない場合に便利です。これにより、タイプのファミリに新しいタイプを追加することもできます。たとえば、Int128をラインに追加すると、数学クラスに影響はありません。 – Dave