82

すべてのプライベート メンバー、次にすべての保護されたメンバー、次にすべてのパブリック メンバーを使用する方がよいでしょうか? それとも逆?それとも、操作をコンストラクターなどから分離できるように、複数のプライベート、プロテクト、およびパブリック ラベルが必要ですか? この決定を行う際、どのような問題を考慮する必要がありますか?

4

16 に答える 16

60

私は公開インターフェースを最初に置きましたが、いつもそうしているわけではありませんでした。私はこれに逆行して、プライベート、保護、パブリックの順で行っていました。振り返ってみると、あまり意味がありませんでした。

クラスの開発者として、おそらくその「内部」に精通しているでしょうが、クラスのユーザーはあまり気にしないか、少なくとも気にする必要はありません。彼らは主にクラスが彼らのためにできることに興味がありますよね?

そのため、私は公共性を第一に考え、通常は機能/ユーティリティ別に整理しています。X に関連するすべてのメソッドを見つけるために私のインターフェースを歩き回る必要はありません。それらすべてを整理された方法で一緒に見てもらいたいのです。

複数の公開/保護/非公開セクションを使用することはありません。私の意見では、混乱しすぎて従うことができません。

于 2008-11-21T12:30:39.073 に答える
43

Google では、「Typedef と列挙型、定数、コンストラクタ、デストラクタ、メソッド (静的メソッドを含む)、データ メンバー (静的データ メンバーを含む)」の順序を優先しています。

Matthew Wilson (Safari のサブスクリプションが必要) は次の順序を推奨しています: 「構築、操作、属性、反復、状態、実装、メンバー、そして私のお気に入り、実装しない」

それらは正当な理由を示しており、この種のアプローチはかなり標準的なように見えますが、何をするにしても一貫性を保つ必要があります。

于 2008-11-21T12:35:10.717 に答える
9

これは私の意見であり、パブリック メソッドを最初に使用する必要があることに、ほとんどの人が同意するだろうと推測します。OO の中核となる原則の 1 つは、実装を気にする必要がないということです。パブリック メソッドを見るだけで、クラスを使用するために知っておく必要があるすべてのことがわかるはずです。

于 2008-11-21T12:19:57.253 に答える
6

いつものように、最初に人間向けのコードを書きます。あなたのクラスを使用する人を考慮し、最も重要なメンバー/列挙型/型定義などを一番上に配置します

通常、これは、クラスのほとんどのコンシューマーが最も関心を持っているパブリック メンバーが一番上にあることを意味します。Protected が次に続き、Private が続きます。いつもの。

いくつかの例外があります。

場合によっては、初期化順序が重要であり、プライベートをパブリックの前に宣言する必要がある場合があります。クラスを継承して拡張することがより重要な場合があり、その場合、保護されたメンバーが上位に配置されることがあります。また、単体テストをレガシ コードにハッキングする場合、パブリック メソッドを公開する方が簡単な場合があります。この大罪をコミットする必要がある場合は、これらをクラス定義の最後に配置します。

しかし、それらは比較的まれな状況です。

ほとんどの場合、「パブリック、保護、プライベート」がクラスの消費者にとって最も役立つことがわかりました。従うのがまともな基本ルールです。

しかし、それはアクセスによる注文ではなく、消費者への関心による注文です。

于 2008-11-21T13:29:27.533 に答える
4

私は通常、最初にインターフェイス(読み取り対象)を定義します。つまり、パブリックであり、次に保護され、次にプライベートなものです。現在、多くの場合、私は一歩前進し、(それを処理できる場合) PIMPL パターンを使用して、実際のクラスのインターフェイスからすべてのプライベートなものを完全に隠しています。

class Example1 {
public:
   void publicOperation();
private:
   void privateOperation1_();
   void privateOperation2_();

   Type1 data1_;
   Type2 data2_;
};
// example 2 header:
class Example2 {
   class Impl;
public:
   void publicOperation();
private:
   std::auto_ptr<Example2Impl> impl_;
};
// example2 cpp:
class Example2::Impl
{
public:
   void privateOperation1();
   void privateOperation2();
private: // or public if Example2 needs access, or private + friendship:
   Type1 data1_;
   Type2 data2_;
};

プライベート (および保護された) メンバーをアンダースコアで後置していることに気付くと思います。PIMPL バージョンには内部クラスがあり、その操作は外部からは見えません。これにより、クラス インターフェイスが完全にクリーンに保たれます。実際のインターフェイスのみが公開されます。順序について議論する必要はありません。

動的に割り当てられたオブジェクトを構築する必要があるため、クラスの構築中に関連するコストが発生します。また、これは、拡張することを意図していないクラスでは非常にうまく機能しますが、階層にいくつかの欠点があります。保護されたメソッドは外部クラスの一部でなければならないため、内部クラスに実際にプッシュすることはできません。

于 2008-11-21T12:54:08.137 に答える
4

私はPOCO C++ Coding Style Guideに従う傾向があります。

于 2008-11-21T13:26:43.080 に答える
2

読みやすさがすべてだと思います。

クラス宣言を開くたびに、パブリック データ メンバーなどを探す場所がすぐにわかるように、それらを固定された順序でグループ化することを好む人もいます。

一般的に、最も重要なことを最初にすべきだと思います。すべてのクラスの 99.6% では、大まかに言えば、パブリック メソッド、特にコンストラクターを意味します。次に、パブリック データ メンバーがあれば (カプセル化は良い考えです)、保護されたメソッドやプライベート メソッドとデータ メンバーが続きます。

これは、大規模なプロジェクトのコーディング標準でカバーされる可能性があるものです。確認することをお勧めします。

于 2008-11-21T12:21:58.310 に答える
2

私たちのプロジェクトでは、メンバーをアクセス順ではなく、使用順で並べています。つまり、使用されているメンバーを並べ替えます。パブリック メンバーが同じクラスのプライベート メンバーを使用する場合、そのプライベート メンバーは通常、次の (単純な) 例のように、どこかでパブリック メンバーの前に配置されます。

class Foo
{
private:
  int bar;

public:
  int GetBar() const
  {
    return bar;
  }
};

ここでは、メンバーバーがメンバーGetBar()の前に配置されています。これは、前者が後者によって使用されるためです。これにより、次の例のように、複数のアクセス セクションが発生する可能性があります。

class Foo
{
public:
  typedef int bar_type;

private:
  bar_type bar;

public:
  bar_type GetBar() const
  {
    return bar;
  }
};

bar_typeメンバーは bar メンバーによって使用さます

どうしてこれなの?わからないのですが、実装のどこかでメンバーに遭遇し、それについての詳細が必要な場合 (そして IntelliSense が再び台無しになっている場合)、作業している場所から上のどこかでそれを見つけることができるのは、より自然なことのように思えました。

于 2008-11-21T13:05:30.967 に答える
2

実際には、それが問題になることはめったにありません。それは主に個人的な好みの問題です。

クラスのユーザーがより簡単に見つけられるように、パブリック メソッドを最初に配置することは非常に一般的です。しかし、ヘッダーはドキュメントの主要な情報源であってはなりません。そのため、ユーザーがヘッダーを見るという考えに基づいた「ベスト プラクティス」は、私には的外れに思えます。

クラスを変更している場合、ヘッダーに人がいる可能性が高くなります。その場合、プライベート インターフェイスに注意する必要があります。

どちらを選択する場合でも、ヘッダーをクリーンで読みやすいものにします。クラスのユーザーであろうとクラスのメンテナーであろうと、たまたま探している情報を簡単に見つけることができることが最も重要です。

于 2009-03-16T09:54:41.767 に答える
1

プライベートフィールドを最初に配置します。

最新のIDEでは、パブリックインターフェイスが何であるかを理解するためにクラスを読むことはありません。

そのためにインテリジェンス(またはクラスブラウザ)を使用するだけです。

誰かがクラス定義を読んでいる場合、それは通常、それがどのように機能するかを理解したいからです。

その場合、フィールドを知ることが最も役立ちます。オブジェクトのパーツが何であるかを示します。

于 2009-03-16T10:08:12.217 に答える
1

全体として、パブリックインターフェイスは何よりも優先する必要があります。これは、クラスのユーザーが関心を持つべき主要な/唯一のことだからです(もちろん、実際には常にそうとは限りませんが、良いスタートです)。

その中で、メンバーの型と定数が最初に最適であり、次に構築演算子、演算、そしてメンバー変数が続きます。

于 2009-03-16T09:39:19.680 に答える
1

クラスを使用してパブリック インターフェイスを最初にリストする人にとっては、非常に役立ちます。それは彼らが気にかけ、使用できる部分です。Protected と Private は後に続くことができます。

パブリック インターフェイス内では、コンストラクター、プロパティ アクセサーとミューテーター、およびオペレーターを個別のグループにグループ化すると便利です。

于 2008-11-21T13:22:38.563 に答える
1

(コンパイラと動的リンカーによって異なりますが)、クラスの最後 (つまり、インターフェイスの最後) に追加するだけで、共有ライブラリの以前のバージョンとの互換性を維持できます。他のものは削除または変更しません。(これは G++ と libtool に当てはまり、GNU/Linux 共有ライブラリの 3 部構成のバージョン管理スキームがこれを反映しています。)

また、メモリの配置による無駄なスペースを避けるために、クラスのメンバーを注文する必要があるという考えもあります。1 つの戦略は、メンバーを最小サイズから最大サイズに並べることです。ただし、C ++またはCでこれを行ったことはありません。

于 2008-11-21T15:47:09.270 に答える
-3

あなたの好みに完全に依存します。「正しい道」はありません。

私自身のペット プロジェクトで C++ を使用する場合、個人的には、各メンバーまたはメソッドの宣言の前にアクセス修飾子を配置するという規則を守っています。

于 2008-11-21T12:25:36.180 に答える