13

私の質問は、フレンド関数と、<<および>>のオーバーロードに関するものです。私の理解から、フレンド関数はプライベートメンバー変数に直接アクセスできる(そしてアクセスすべきである)と思いました。ただし、ここにある場合、コンパイラは、「get」関数を使用して各プライベート変数を取得したときにのみ、.cxxファイルを受け入れます。

これが私のヘッダーファイルです

class BigNum 
public:

// CONSTRUCTORS and DESTRUCTORS
    BigNum();                            
    BigNum(int num, size_t optional_base = 10);                         
    BigNum(const char strin[], size_t optional_base = 10);

// MEMBER FUNCTIONS
    size_t get_digit(size_t index) const;
    size_t get_used() const;
    size_t get_capacity() const;
    size_t get_base() const;
    bool get_sign() const;

// FRIEND FUNCTIONS
    friend std::ostream& operator<<(std::ostream &os, const BigNum &bignum);
    friend std::istream& operator>>(std::istream &is, BigNum &bignum);

private:
    size_t base;            
    size_t *digits;          
    bool positive;          
    size_t used;              

これは、フレンド関数の実装を含む対応する.cxxファイルです。

#include "file.h"
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

std::ostream& operator <<(std::ostream &os, const BigNum &bignum)
{
if (bignum.get_sign() == false)
    os << '-';

for (size_t i = 0; i < bignum.get_used(); ++i)
    os << bignum.get_digit(bignum.get_used() - i - 1);

return os;
}

std::istream& operator >>(std::istream &is, BigNum &bignum)
{
for (size_t i = 0; i < bignum.get_used(); ++i)
    is >> bignum.digits[i];

return is;
}

したがって、この点で、上記のフレンド演算子は正しくコンパイルされました。ただし、私の演算子>>が1つのプライベート変数に直接アクセスできるのはなぜですか(>> bignum.digits [i])が、残りのプライベート変数は「getfunctions」で取得する必要があります

以下、この点でオーバーロード演算子を書き込もうとすると(フレンド関数がプライベート変数を適切に呼び出す必要があると私が考えた方法):

std::ostream& operator <<(std::ostream &os, const BigNum &bignum)
{
if (bignum.positive == false)
    os << '-';

for (size_t i = 0; i < bignum.used; ++i)
    os << bignum.digits[used - i - 1];

return os;
}

std::istream& operator >>(std::istream &is, BigNum &bignum)
{
for (size_t i = 0; i < bignum.used); ++i)
    is >> bignum.digits[i];

return is;
}

以下のエラーが発生します。

BigNum2.cxx: In function `std::ostream&
   csci2270_hw1B::operator<<(std::ostream&, const csci2270_hw1B::BigNum&)':
BigNum2.cxx:201: error: `used' undeclared (first use this function)
BigNum2.cxx:201: error: (Each undeclared identifier is reported only once for
   each function it appears in.)
BigNum2.cxx: In function `std::istream&
   csci2270_hw1B::operator>>(std::istream&, csci2270_hw1B::BigNum&)':
BigNum2.cxx:208: error: syntax error before `)' token

私が使用しているコンパイラはg++(バージョン3.3.1)です。どんな助けでもありがたいです、ありがとう。

改訂:

bignumオブジェクトがプライベート変数にアクセスできるようにコードを更新しました。フレンド演算子のオーバーロード<<に対して次のことを行い、正常にコンパイルされました。コメントありがとう、それは新人の間違いでした。

std::ostream& operator <<(std::ostream &os, const BigNum &bignum)
{
if (bignum.positive == false)
    os << '-';

for (size_t i = 0; i < bignum.used; ++i)
    os << bignum.digits[bignum.used - i - 1];

return os;
}

ただし、コンパイラはまだ>>演算子のエラーを生成しています

BigNum2.cxx:関数内std::istream& csci2270_hw1B::operator>>(std::istream&, csci2270_hw1B::BigNum&)': BigNum2.cxx:208: error: syntax error before)'トークン

>>は数値を読み込むことになっており、プライベートメンバー変数'used'は配列の長さを記録することになっています。コンパイラがなぜ受け入れるのか、私はまだ少し混乱しています

std::istream& operator >>(std::istream &is, BigNum &bignum)
{
for (size_t i = 0; i < bignum.get_used()); ++i)
    is >> bignum.digits[i];

return is;
}

とは対照的に:

std::istream& operator >>(std::istream &is, BigNum &bignum)
{
for (size_t i = 0; i < bignum.used); ++i)
    is >> bignum.digits[i];

return is;
}

何かご意見は?ありがとう。

4

3 に答える 3

10

フレンド関数はクラスのプライベート データにアクセスできますが、それを自動化するためのポインターを取得しないため、クラスのデータ (プライベートまたはその他) へのすべてのアクセスを修飾する必要があります。thisたとえば、次のようになります。

os << bignum.digits[used - i - 1];

する必要があります:

os << bignum.digits[bignum.used - i - 1];
于 2010-07-22T18:56:19.640 に答える
5

最初の関数で修飾されていませんused- である必要がありますbignum.usedthis演算子のオーバーロードはグローバル スコープで定義されるため、ポインターを取得しません。ただし、フレンド関数はクラスのプライベート メンバーにアクセスできます。

std::ostream& operator <<(std::ostream &os, const BigNum &bignum) 
{ 
    if (bignum.positive == false) 
        os << '-'; 

    for (size_t i = 0; i < bignum.used; ++i) 
        // Note "bignum.used", instead of "used".
        os << bignum.digits[bignum.used - i - 1];     
    return os; 
} 

std::istream& operator >>(std::istream &is, BigNum &bignum) 
{ 
    for (size_t i = 0; i < bignum.used; ++i) 
        is >> bignum.digits[i]; 

    return is; 
} 
于 2010-07-22T18:56:15.050 に答える
2

次の行の bignum.used の直後に余分な ')' があるようです。

 for (size_t i = 0; i < bignum.used**)**; ++i)
于 2014-11-29T19:19:42.100 に答える