9

このスタイルガイドは私には役に立ちましたが、ルール#5に出くわしました。

一般に、このような定数の使用は最小限に抑える必要があります。多くの場合、メソッドとして値を実装することをお勧めします。

int getMaxIterations() // NOT: MAX_ITERATIONS = 25
{
    return 25;
}

私はスタイルの観点から推論を理解しています:「叫ぶ」定数宣言を廃止するだけでなく、使用中の言語構造の数を減らし(これが間違った用語である場合は許してください)、理解しやすいプログラム。

ただし、このアプローチはコンパイラに蔑称的な影響を及ぼしますか、それとも最新のコンパイラ(または実際には古いコンパイラ..)は、getMaxIterations関数が毎回同じ数を返していることを判断するのに十分な先読みができますか?

確かに、そして考え直してみると、コンパイラーは先を見越す必要さえありますか?スタイルガイドは、メソッドアプローチが定数値を使用するよりも優れていることを示唆しています。これは、「定数」値を、どのスコープで使用した後でもメモリに保持する必要がないためだと思いますか?

要約すると、私の質問は次のとおりです。定数値の使用は推奨されていませんか?もしそうなら、なぜですか?

(ボーナスポイントについては、定数をメソッドとして宣言することと定数として宣言することの技術的な違いは何ですか?)

4

4 に答える 4

4

その理由の1つは、バートランド・メイヤーが「統一参照の原則」(IIRC)と呼んでいるものです。

彼は銀行口座と現在の残高の例を使用しました。これはデータメンバーまたは関数/メソッドである必要がありますか?Meyerは、このタイプの決定は、ソフトウェアプロジェクトの存続期間中に、場合によっては数回変更される可能性が高いと主張しています。したがって、残高が現在データメンバーとして表されている場合でも、ゲッターでラップする必要があります。そうすれば、実装を変更する必要がある場合でも、インターフェースを変更する必要はありません...したがって、このクラスのクライアントは、実装の変更から隔離されます。

別の言い方をすれば、これは現在は一定ですが、計算する必要がある時点にいることに気付くかもしれません。

そして、他の人が指摘しているように、最新のコンパイラーは(うまくいけば)メソッドの実装をインライン化するのに十分スマートであり、メソッドにすることでパフォーマンスが低下することはありません。

于 2012-09-26T20:51:09.253 に答える
4

これは、ほとんどのコンパイラに組み込まれています。

そうは言っても、スタイルガイドがポイントを作っています。これを行う代わりに、次のように表示されます。

#define FOO_MAX_ITERATIONS 25
struct Foo {
  void do_it() { for(int i = 0; i < FOO_MAX_ITERATIONS; i++) iterate(); }
};

代わりにこれである必要があります:

struct Foo {
  int getMaxIterations() { return 25; }
  void do_it() { for(int i = 0; i < getMaxIterations(); i++) iterate(); }
};

ご覧のとおり、長期的にははるかに一貫性があり読みやすく、クラスから継承する場合など、将来の設計に適しています。後で、getMaxIterations()を実行時に変更したい場合があり、#define FOO_MAX_ITERATIONS someMethod()のような醜いハックを行う必要はありません。

正常なC++11コンパイラ(つまり、Visual Studioではない)を使用している場合、そのような関数はさらに次のように宣言する必要があります。

struct Foo {
  constexpr int getMaxIterations() { return 25; }
  void do_it() { for(int i = 0; i < getMaxIterations(); i++) iterate(); }
};

getMaxIterations()の宣言のconstexprに注意してください。これは、C ++ 11コンパイラに「定数式」であり、コンパイル時に評価できることを示しています。これにより、他のコンパイル時宣言で使用できるようにするなど、コンパイル前にgetMaxIteratsion()を25に直接置き換えることができます。

于 2012-09-26T20:45:32.153 に答える
3

いいえ。実際、それは奨励されています。以前のコンパイラconstexpr(および最新のMSVCも多数あります)は、関数呼び出しを定数値として使用できません。

std::array<int, getMaxIterations()> arr; // bad
std::array<int, MaxIterations> arr; // fine

そのガイドは間違った巨大な山です。44を検討してください

クラスの一部は、パブリック、プロテクト、プライベートにソートする必要があります[2][3]。すべてのセクションを明示的に識別する必要があります。該当しないセクションは省略してください。

これは明らかに間違っています。パブリックAPIはプライベートなものに依存しているため、多くの場合、それらをインターリーブする必要があります。この厳密な順序付けは、純粋に宣言の順序のために、いくつかの種類のAPIを禁止します。簡単な例は、プロキシオブジェクトや式テンプレートなどによく使用されるプライベートタイプを返す場合、またはパブリックメソッドの実装がプライベートテンプレートメソッドに依存している場合です。プライベートテンプレートメソッドは、使用する前に完全に定義する必要があります。

于 2012-09-26T20:46:00.067 に答える
0

定数値を宣言することと、このスタイルガイドが示唆する方法でメソッドを使用することには、大きな違いが1つあります。

メソッド宣言:

int getMaxIterations()
{
  return 25;
}

getMaxIterationsの値を取得すると、メソッドが呼び出されるオブジェクトの状態を変更できることを意味します。これは、constオブジェクトの最大反復値が何であるかを知ることができないことを意味します。また、マルチスレッド環境でメソッドを呼び出すのは安全ではない可能性があることも意味します。これは明らかに正しくありません。メソッドは次のように宣言する必要があります。

int getMaxIterations() const;
于 2012-09-26T21:47:14.863 に答える