2013-03-05 7 views
1

Я пытаюсь создать не-член operator<<. Однако я хочу, чтобы оператор был доступен для двух моих классов. ОператорКак использовать функцию друга в нескольких классах

void operator<< (ClassA & a, ClassB & b) 

В двух классах публичной части, я говорю:

friend void operator<< (ClassA & a, ClassB & b); 

Однако, оказалось, что оператор может получить доступ к переменной-члена в CLass B, но не может получить доступ к частной переменной члена в Class A.

Почему?

Реальный код: В файле CPP:

void operator<< (Hand& h, Deck& d){ 

    h.hand.push_back(d.card[0]); 
    sort(h.hand.begin(),h.hand.end()); 
    d.card.erase(d.card.begin()); 
} 

В заголовочном файле:

class Deck { 

private: 
    vector<Card> card; 

public: 
    friend void operator<< (Hand& , Deck&); 
}; 

class Hand { 

private: 
    vector<Card> hand; 

public: 
    friend void operator<< (Hand& , Deck&); 
}; 

И картотека не работает.

+1

Пока вы поставите друг декларацию в обеих классах, она должна быть тонкой. Возможно, что-то не так с этими декларациями или с определением вашего оператора. Вы должны показать реальный код –

+0

Вы уверены, что хотите << вернуть void? Вы не сможете привязать или использовать возвращаемое значение и обязательно внесите в свой код «gotchas». – milleniumbug

+0

@milleniumbug "конечно"? Это чепуха. Это не оператор ввода потока. Вы все равно можете реализовать перегрузку вставки потока оператора без проблем, не создавая особых проблем. Тем не менее, я бы предпочел, чтобы это была неоператорная функция. – sehe

ответ

2

Update отредактированного вопрос: следующий код не компилируется никакой проблемы для меня:

#include <vector> 
#include <algorithm> 
typedef int Card; 

class Hand; // NOTE forward declaration 

class Deck { 
private: 
    std::vector<Card> card; 

public: 
    friend void operator<< (Hand& , Deck&); 
}; 

class Hand { 
private: 
    std::vector<Card> hand; 

public: 
    friend void operator<< (Hand& , Deck&); 
}; 

void operator<< (Hand& h, Deck& d) { 
    h.hand.push_back(d.card[0]); 
    std::sort(h.hand.begin(),h.hand.end()); 
    d.card.erase(d.card.begin()); 
} 

int main() 
{ 
} 

Вы забыли вперед объявить Руку в заголовочном файле?


Вы можете спутать, потому что вы можете определить тело статической функции друг внутри одной из деклараций класса.

Все еще, друг декларация - это всегда только объявление . Таким образом, на самом деле

struct A; 
struct B; 

struct A 
{ 
    friend bool operator<<(A const&, B const&); 
}; 

struct B 
{ 
    friend bool operator<<(A const&, B const&); 
}; 

bool operator<<(A const&, B const&) 
{ 
    // access to both A and B 
    return false; 
} 

Эквивалентен, чтобы

struct A; 
struct B; 

struct A 
{ 
    friend bool operator<<(A const&, B const&) 
    { 
     // access to both A and B 
     return false; 
    } 
}; 

struct B 
{ 
    friend bool operator<<(A const&, B const&); 
}; 
+0

Хм, как это связано с вопросом? – Slava

+0

@Slava Обратите внимание, что вопрос был отредактирован, я ответил, когда он сказал http://stackoverflow.com/revisions/15232809/2. Я также просто обновил свой ответ соответственно – sehe

+0

Я вижу спасибо, я тоже думал о форвардной декларации, но может ли объявление объявления этого друга компилироваться без предварительного объявления класса? – Slava

Смежные вопросы