2012-01-13 4 views
1

組み込みのC++データ型を独自のクラスにカプセル化する場合、どのような欠点(パフォーマンスやその他の欠点)が発生するのかを議論することはありません。たとえば、JavaやC#と同様に、intデータ型はIntという独自のクラスを持ち、インライン演算子でオーバーロードします。シングル、ダブル、ロングなどと同じ基本データ型をクラスにカプセル化する

+6

私は反対の質問をすることはできますか?利点は何でしょうか? –

+0

このような「透過」ラッパーと同様に、「演算子」のセマンティクスは失われる状況になります。 – Jon

+0

1つの利点は、それらが基本クラスを継承できることです。 Int32:整数:数値:オブジェクトです。これは、単純にIntegerまたはRealで十分である場合に、多くのタイプのMathクラスに過負荷をかけたくない場合に便利です。これにより、タイプのファミリに新しいタイプを追加することもできます。たとえば、Int128をラインに追加すると、数学クラスに影響はありません。 – Dave

答えて

5

利点はありません。あなたは、同じ行動やパフォーマンスを達成することはできません。


欠点:

  • パフォーマンスはビルトインタイプよりも速くなることはありません。あなたが得られる最高のものは、すべてが組み込みの型コードにインライン展開されるクラスですが、そのポイントは何ですか?
  • 、このような事業者が
  • 非自明なコンストラクタ(必ずしも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などのクラスで機能します。

+1

「あなたはJavaがあなたの頭に詰まっています。」 - それを出す方法があるのだろうか? :) –

+0

エミュレートできない動作を詳しく説明できますか? –

+0

実際にはC#が頭に突き刺さって、Javaの頭がMicrosoftの頭にぶつかった.-P – Dave

2

クラリティは苦しみますが、それはほとんどの場合です。

スマートコンパイラを使用している場合は、単にintをラップし、操作を変更しないクラスは完全にインライン展開される可能性があります。コンストラクタを明示的に定義しないと、void f(OurVerySpecialInt i)にはf(15)と書くこともできます。しかし、もしあれば、あなたの非常に特別な機能を既存の機能に渡すのは難しいでしょう。

クラスだけでなく、クラス階層を意味する場合は、状況は非常に異なります。あなたはNumericを抽象基本クラスとし、それに派生するのはIntDoubleにしますか?その場合は、再検討してください。かなり遅いコードで終わる可能性が高いだけでなく、これを一般的かつ正気にする方法は実際にはありません。

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を大きくすることはできないので、それをエラーにするか、オーバーフローさせてください。基本的にはpNumeric*の場合、*p += 50000;が何をするかわからない:*p += 5.3を実行したときに精度が失われているかどうかを知ることはできません。

条件を厳密にしてこれらのエラーを修正すると、継承を必要としない何らかの種類のRationalまたはBigIntになります。すべての動作は厳密に(それが数学的実体であるべきであるように)厳密に指定されているので、それから派生しても何も変更できません。

これで十分ではない場合は、Numericクラスに仮想メソッドを指定した場合、すべての派生クラスにvtable(一般的な実装では)があることに注意してください。これは、クラスのすべてのインスタンスが通常よりも少しスペースを必要とすることを意味し、すべての数値を2倍にすると、実行していることによってパフォーマンスが大幅に低下する可能性があります。

関連する問題