2

効果的な C++は、「メンバー関数よりも非メンバー非フレンド関数を優先する」(項目 23) と述べています。理論的根拠は私には理にかなっています.APIの「表面積」を最小限に抑えます。しかし、実際には、人々 (私自身を含む) を説得するのが難しいと感じることがよくあります。たとえば、いくつかの形状クラスがあり、それらが周長と面積の計算をサポートしているとします。

// @interface
class Shape {
 public:
  virtual double Area() = 0;
  virtual double Perimeter() = 0;
}

class Rectangle : public Shape {
 public:
  Rectangle(double width, double height);

  double width();
  double height();

  ...
};

class Circle : public Shape {
 public:
  Circle(double radius);

  double radius();
  ...
};

このアドバイスによると、Area と Perimeter は非メンバー非フレンド関数 (メソッドではない) である必要があるようです。たとえば、Rectangle の面積は、幅と高さのメソッドから次のように計算できます。

double Area(const Rectangle& rectangle) {
  return rectangle.width() * rectangle.height();
}

実際、Rectangle も Circle も、getter によって公開されていない内部状態を持っておらず、それがどのように当てはまるかを想像するのは困難です。したがって、これらを操作する関数はメソッドであってはなりません。もう一つの例:

// The diameter of a shape is the (circle) diameter of the smallest circle
// that contains a shape.
double Diameter(const Rectangle& rectangle) {
  double w = rectangle.width();
  double h = rectangle.height();
  return sqrt(w * w + h * h);
}

ここで何か不足していますか?それとも、これは実際には悪いアドバイスですか??

4

2 に答える 2

5

多形オブジェクトの面積を計算する必要がある場合Shape、Scott のアドバイスは当てはまりません。外部関数を使用して面積を計算することはできません。実際には、必要な情報へのパブリック アクセスがないためです。つまり、オブジェクトが実際に円なのか、長方形なのか、それ以外なのか。したがって、これは仮想機能の仕事です。

実際、関数の正しい配置を決定するための Scott の疑似コード アルゴリズム (本を持っていないため、この記事から引用) では、最初のテストは次のとおりです。

if (f needs to be virtual)
    make f a member function of C;
于 2013-08-24T14:53:29.213 に答える
0

getter と setter を介して直接アクセスできるいくつかの変数を持つクラスがある場合、何ができますか? structそうです、「オブジェクト指向」のファサードを備えたものに他なりません。このようなデータコンテナーの使用に関して、オブジェクト指向のものはまったくありません。

オブジェクト指向の要点は、私が理解しているように、データではなく動作をモデル化することです。この点で、面積と周長を計算するための純粋な仮想メソッドを備えた抽象形状クラスは、完全に有効な設計です。データから抽象化し、必要な動作を公開します。私があなただったら、基本的なパラメーターのゲッターを追加することについて 2 回考え (有用な抽象化はありません)、それぞれのセッターを追加することについて 3 回考えます (カプセル化を破る)。

ただし、アクセサーを使用するか使用しないか、単純で単純な古いデータ構造を避けること、さらにはオブジェクト指向の設計についても、絶対に宗教的にならないようにしてください。これにはすべて用途があり、回避するために回避すると、いずれかの場合に貧弱な設計につながります。私が言いたいのは、自分のニーズに何が最も適しているかを考えてから、一部の大物プログラマーが思いついた宗教的な規則にまったく関心を持たずにそれを実行することです。

于 2013-08-24T15:15:36.797 に答える