静電気を多量に使用することは悪いことですか、それとも良いことですか?

StackOverflow https://stackoverflow.com/questions/30998

  •  09-06-2019
  •  | 
  •  

質問

私は、C# と同様に、静的関数を分類する方法として C++ で静的関数を使用することを好みます。

Console::WriteLine("hello")

これは良いことですか、それとも悪いことですか?関数が頻繁に使用される場合は問題ないと思いますが、そうでない場合はメモリを圧迫しますか?

どうですか static const?

役に立ちましたか?

解決

しかしそれは良いことなのか悪いことなのか

最初に思い浮かぶ形容詞は「不必要」です。C++ には自由な関数と名前空間がありますが、なぜそれらをクラス内で静的関数にする必要があるのでしょうか?

C# および Java のインスタンス化できないクラスでの静的メソッドの使用 回避策です これらの言語には無料の関数 (つまり、クラスの一部としてではなく、名前空間に直接存在する関数) がないためです。C++ にはそのような欠陥はありません。名前空間を使用するだけです。

他のヒント

私は静的の使用に大賛成です 機能. 。これらは、特にモジュールに編成された場合に意味を成します (static class C# で)。

しかし、 瞬間 これらの関数には、ある種の外部 (コンパイル時以外の const) データが必要な場合、その関数をインスタンス メソッドにして、そのデータとともにクラスにカプセル化する必要があります。

一言で言えば:静的関数は問題ありませんが、静的データは問題ありません。

静的関数を名前空間で置き換えることができると言う人は間違っています。簡単な例を次に示します。

class X
{
   public:
   static void f1 ()
   {
      ...
      f2 ();
   }

   private:
     static void f2 () {}
};

ご覧のとおり、パブリック静的関数 f1 別の静的だがプライベートな関数を呼び出します f2.

これは単なる関数のコレクションではなく、独自のカプセル化されたメソッドを備えたスマートなコレクションです。名前空間ではこの機能は提供されません。

多くの人が「シングルトン」パターンを使用します。これは一般的な慣行であるためです。しかし、多くの場合、複数の静的メソッドと 1 つの静的データ メンバーだけを含むクラスが必要になります。この場合、シングルトンはまったく必要ありません。メソッドも呼び出す instance() 静的関数/メンバーに直接アクセスするよりも遅くなります。

名前空間を使用して関数のコレクションを作成します。

namespace Console {
    void WriteLine(...) // ...
}

メモリに関しては、関数は関数の外部、静的メンバー関数または名前空間内で同じ量を使用します。あれは:コード自体以外の記憶はありません。

静的データが不適切である具体的な理由の 1 つは、C++ がさまざまな翻訳単位での静的オブジェクトの初期化順序を保証していないことです。実際には、あるオブジェクトが異なる翻訳単位内の別のオブジェクトに依存している場合、これにより問題が発生する可能性があります。Scott Meyers は、著書『More Effects C++』の項目 26 でこれについて説明しています。

ここでの Frank の意見に同意します。静的 (グローバル) 関数には問題はありません (もちろん、それらが整理されていれば)。人々が「ああ、このデータの範囲をもう少し広げてみよう」と考えたときにのみ、問題が本格的に発生し始めます。滑りやすい坂道 :)

本当に視野に入れて考えると.. 関数型プログラミング ;)

静的関数の問題は、カプセル化を破壊するデザインにつながる可能性があることです。たとえば、次のようなことを書いているとします。

public class TotalManager
{
    public double getTotal(Hamburger burger)
    {
        return burger.getPrice() + burget.getTax();
    }
}

...その場合は、デザインを再考する必要があるかもしれません。静的関数では、多くの場合、クラスの API が乱雑になり、一般的に物事がより複雑になるセッターとゲッターを使用する必要があります。私の例では、Hamburger のゲッターを削除し、getTotal() クラスを Hamburger 自体に移動する方が良いかもしれません。

私は静的関数で構成されるクラスを作成する傾向がありますが、これを行うための「正しい方法」は通常、代わりに名前空間を使用することだと言う人もいます。(私は C++ に名前空間が存在する前に習慣を身につけました。)

ところで、静的データと関数のみで構成されるクラスがある場合は、コンストラクターをプライベートとして宣言して、誰もインスタンス化しようとしないようにする必要があります。(これが、クラスではなく名前空間を使用するべきだと主張する理由の 1 つです。)

編成には、すでに述べたように名前空間を使用します。

グローバル データの場合は、 シングルトン このパターンは、静的オブジェクトの不明な初期化順序の問題を解決するのに役立つためです。言い換えれば、オブジェクトをシングルトンとして使用する場合、使用時に初期化されることが保証されます。

また、静的関数がスレッドセーフであるようにステートレスであることも確認してください。

私は通常、静的機能をフレンド システムと組み合わせてのみ使用します。

たとえば、プライベート データの操作を含む計算を行うために多くの (インライン化された) 内部ヘルパー関数を使用するクラスがあります。

もちろん、これにより、クラス インターフェイスが持つ関数の数が増加します。これを取り除くために、元のクラス .cpp ファイルでヘルパー クラスを宣言し (したがって外部には見えないようにする)、それを元のクラスのフレンドにして、古いヘルパー関数を静的 (インライン) メンバーに移動します。ヘルパー クラスの関数。古いパラメータに加えて参照ごとに古いクラスを渡します。

これにより、インターフェイスがスリムになり、無料の友達機能を大量にリストする必要がなくなります。インライン化もうまく機能するので、私は静的を完全に反対しているわけではありません。(私はできる限りそれを避けていますが、このように使用するのは好きです。)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top