1

以下はコードです

コード:

#include <iostream>
using namespace std;

class Rational {
  int num;  // numerator
  int den;  // denominator
  friend istream& operator>> (istream & , Rational&);
  friend ostream& operator<< (ostream &  , const Rational&);
 public:
  Rational (int num = 0, int den = 1)
    :     num(num), den(den) {}
  void getUserInput() {
    cout << "num = ";
    cin >> num;
    cout << "den = ";
    cin >> den;
  }
  Rational operator+(const Rational &);
};

Rational Rational::operator+ (const Rational& r) { //HERE 
  int n = num * r.den + den * r.num;
  int d = den * r.den;
  return Rational (n, d);
}

istream& operator>> (istream & is , Rational& r)
{
    is >> r.num >> r.den;
}

ostream& operator<< (ostream & os , const Rational& r)
{
    os << r.num << " / " <<  r.den << endl;;
}
int main() {
  Rational r1, r2, r3;
  cout << "Input r1:\n";
  cin >> r1;
  cout << "Input r2:\n";
  cin >> r2;
  r3 = r1 + r2;
  cout << "r1 = " << r1;
  cout << "r2 = " << r2;
  cout << "r1 + r2 = " << r3;
  return 0;
}

質問

上記のコードにはoperator+のオーバーロードがあり、operator +の定義ではr、プライベートデータ(r.numおよびr.den)にアクセスするパラメーターを確認できます。C ++がパラメータにクラス外のプライベートデータへのアクセスを許可するのはなぜですか?それはある種の特別な場合ですか?

ありがとうございました。

4

5 に答える 5

3

アクセス指定子はインスタンスではなくクラスのレベルで適用されるため、Rationalクラスは他の Rationalインスタンスのプライベートデータメンバーを見ることができます。yourRational operator+はメンバー関数であるため、Rational引数のプライベートデータにアクセスできます。

注:標準的なアプローチは、メンバーを定義し、operator +=それを使用して非メンバーを実装することです。operator+

struct Foo
{
  int i;

  Foo& operator+=(const Foo& rhs) 
  { 
    i += rhs.i;
    return *this;
  }

};

Foo operator+(Foo lhs, const Foo& rhs)
{
  return lhs += rhs;
}
于 2012-09-12T14:26:31.567 に答える
1

他のポスターはC++アクセス指定子がどのように機能するかを説明していますが、なぜこのように機能するのかは誰も説明していません。

カプセル化を増やすことは、オブジェクトの数ではなく、オブジェクトの内部(つまり、データメンバー)にアクセスできるコードの量を最小限に抑えることです。アクセス指定子が同じクラス内の他のオブジェクトの内部へのアクセスを制限している場合、これによってカプセル化が増えることはありません。

カプセル化は、実装の詳細を変更すると最小限のコードに影響することを意味するため、重要です。カプセル化を増やすと、コードの保守性が向上します。これはビルド時であり、ランタイムの概念ではありません。

于 2013-01-13T15:28:59.087 に答える
1

C ++がパラメータにクラス外のプライベートデータへのアクセスを許可するのはなぜですか?それはある種の特別な場合ですか?

アクセス指定子のルールは次のとおりです。
「アクセス指定子はオブジェクトごとではなくクラスごとに適用されます」したがって、クラスオブジェクトのメンバーには、そのクラスのメンバー関数で
いつでもアクセスできます。private

コピーコンストラクター/コピー代入演算子は、ルールの一般的に使用される例ですが、それほど頻繁には気づきません。

オンラインサンプル

class Myclass
{
    int i;
    public:
       Myclass(){}
       Myclass(Myclass const &obj3)
       { 
            //Note i is private member but still accessible
            this->i = obj3.i;
       }
};

int main()
{
    Myclass obj;
    Myclass obj2(obj);
}

良い読み物:
アクセス指定子とは何ですか?プライベート、保護、またはパブリックで継承する必要がありますか?

于 2012-09-12T14:29:05.380 に答える
1

Rational::operator+はメンバー関数であるため、すべてのオブジェクトのすべてのメンバーにアクセスできます。 Rational

operator+=コーディングのヒント:この種のものは通常、メンバーであるものとそうでないものの2つの部分で記述されoperator+ます。このような:

Rational& Rational::operator+=(const Rational& rhs) {
    num = num * rhs.den + den * rhs.num;
    den *= rhs.den;
    return *this;
}

Rational operator+(const Rational& lhs, const Rational& rhs) {
    Rational result(lhs);
    result += rhs;
    return result;
}
于 2012-09-12T14:31:42.623 に答える
1

質問は誤解を明らかにします:「なぜC ++はパラメータがクラスの外のプライベートデータにアクセスすることを許可するのですか?」

メソッドoperator+はクラスに属します:クラス内で宣言され、その実装では、メソッドがプレフィックスclass_name ::によってクラスのメンバーであることがわかります。したがって、operator +では、クラス。

演算子<<と>>は別のケースです。これらはストリームオブジェクトによって呼び出されるため、実際にはクラスに属していません。そのため、それらの実装には接頭辞Rational::がありません。これらの演算子がオブジェクトのプライベートデータにアクセスできるようにするために、クラス宣言内でクラスのフレンドであると宣言されています。関数またはクラスを自分のクラスの友達であると宣言することにより、クラスのプライベートデータを改ざんしないように信頼していることを示します。

于 2014-06-28T05:54:03.247 に答える