14

これは、2 つのフレンド関数を含む、一連の演算子と関数を含む文字列クラスであると想定されています。そして、これらの 2 つは、プライベート メンバーにアクセスできないとコンパイラが言うため、私に問題を引き起こします。ここに私のstring.hがあります:

#include <iostream>
#ifndef STR_H
#define STR_H

namespace MyStr
{
class Str
{
private:
    unsigned int length;
    char *data;
public:
    Str();
    Str(const Str&);
    Str(const char*);
    Str(char c, unsigned int db);
    ~Str();
    char* cStr() const;
    unsigned int getLength() const;

ここには無関係な機能がたくさんあります...

    friend int operator/ (const Str&, char);
    friend std::ostream& operator<< (std::ostream&, const Str&);
};
}
#endif /* STR_H */

ここにmain.cppがあります:

#include <iostream>
#include "Str.h"

using namespace std;
using namespace MyStr;

ostream& operator<< (ostream& out,const Str& str)
{
    for (int i=0; i<str.length; i++)
    {
        out<<str.data[i];
    }
    out<<endl;
    return out;
}

int operator/ (const Str& str, char c)
{
    for (int i=0; i<str.length; i++)
    {
        if(str.data[i]==c) return i;
    }
    return -1;
}

Strこのコードはコンパイルされず、コンパイラはメンバーが非公開であると主張します。

4

2 に答える 2

23

名前空間にもっと注意を払う必要があります。

class Str {
private:
    unsigned int length;
    char *data;
public:
    Str(){}
    Str(const Str&){}
    Str(const char*){}
    Str(char c, unsigned int db){}
    // maybe something more...
    friend int operator/ (const Str&, char);
    friend std::ostream& operator<< (std::ostream&, const Str&);
};

ostream& operator<< (ostream& out,const Str& str)
{
    for (int i=0; i<str.length; i++)
        out<<str.data[i];
    out<<endl;
    return out;
}

int operator/ (const Str& str, char c)
{
    for (int i=0; i<str.length; i++)
        if(str.data[i]==c) return i;

    return -1;
}

int main()
{
    Str s;
    cout<<s;
    return 0;
}

名前空間が一致しないため、エラーが発生します。固執したい場合は、オーバーロードされたフレンドオペレーターMyStrに名前空間を追加する必要があります。これを行う方法は次のとおりです: (演算子は名前空間内で定義する必要があります)MyStrMyStr

namespace MyStr {  
    ostream& operator<< (ostream& out,const Str& str)
    {
        for (int i=0; i<str.length; i++)
        {
             out<<str.data[i];
         }
        out<<endl;
        return out;
    }

    int operator/ (const Str& str, char c)
    {
        for (int i=0; i<str.length; i++)
        {
            if(str.data[i]==c) return i;
        }
        return -1;
    }
}
于 2013-03-31T16:23:35.733 に答える
9

内部でフレンド関数を宣言すると、Strそれらはすぐに外側の名前空間にあると見なされますMyStr

定義する演算子はグローバル名前空間にあるため、コンパイラは、それらが 2 つのまったく異なる演算子であり、友達ではないと認識します。

追加することでこれを解決できます

namespace MyStr
{

}

.cpp ファイルの演算子を囲みます。

于 2013-03-31T16:19:54.503 に答える