2013-03-31 11 views
11

To ma być klasa łańcuchowa z wieloma operatorami i funkcjami, w tym dwiema funkcjami znajomego. A ci dwaj sprawiają mi kłopoty, ponieważ kompilator mówi, że nie mają dostępu do prywatnych członków. Oto moja string.h:Funkcja przyjaciela C++ nie może uzyskać dostępu do prywatnych członków.

#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; 

wiele irrevelant funkcji tutaj ...

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

Oto 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; 
} 

Ten kod nie będzie kompilować, kompilator twierdzący, że członkowie Str są prywatni.

+1

Jakie błędy dostaniesz? – 0x499602D2

+0

error: 'char * MyStr :: Str :: data' jest prywatne | error: 'unsigned int MyStr :: Str :: length' jest prywatne | – spinakker

+0

W jakiej linii emituje ten błąd? Czy jest to dla obu funkcji? – 0x499602D2

Odpowiedz

15

Powinieneś zwrócić większą uwagę na przestrzenie nazw.

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; 
} 

Otrzymujesz błąd ze względu na niedopasowane przestrzenie nazw. Jeśli wolisz trzymać się z MyStr, powinieneś dodać przestrzeń nazw MyStr, aby przeładować operatorów znajomych. Oto, jak możesz to zrobić: (operatory powinny być zdefiniowane w przestrzeni nazw MyStr)

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; 
    } 
} 
7

Po zadeklarowaniu funkcji znajomego w postaci Str są one uważane za znajdujące się w natychmiastowym otaczającym obszarze nazw, MyStr.

Operatory, które definiujesz, znajdują się w globalnej przestrzeni nazw, więc kompilator uważa, że ​​są to dwa zupełnie różne operatory, a nie przyjaciele.

Problem ten można rozwiązać poprzez dodanie

namespace MyStr 
{ 

} 

wokół operatorów w pliku .cpp.

+0

To zadziałało! Dziękuję bardzo. Muszę nauczyć się korzystać z tych przestrzeni nazw ... – spinakker

+0

Próbuję tego i to nie działa - http://liveworkspace.org/code/4yc7Hy$3217 – 0x499602D2

+0

@David - To jest inne. Próbujesz uzyskać dostęp do 's.x' wewnątrz głównego, a główny nie jest przyjacielem klasy. –

Powiązane problemy