2014-11-02 5 views
1

Я столкнулся с некоторыми проблемами при работе над функциями друзей. Я хочу использовать функцию друга, которая использует два разных класса в параметрах. Вот пример кода:Функция друга, которая принимает 2 класса в параметрах - «класс» не определен

ObjectA.h:

#ifndef OBJECTA_H_ 
#define OBJECTA_H_ 

#include "ObjectB.h" 

#include <iostream> 
using namespace std; 

class ObjectA { 
private: 
    friend void friendFunction(ObjectA &,ObjectB &); 

public: 
    ObjectA(); 
    virtual ~ObjectA(); 
}; 

#endif /* OBJECTA_H_ */ 

ObjectB.h:

#ifndef OBJECTB_H_ 
#define OBJECTB_H_ 

#include <iostream> 
using namespace std; 

#include "ObjectA.h" 

class ObjectB { 
private: 
    friend void friendFunction(ObjectA &, ObjectB &); 

public: 
    ObjectB(); 
    virtual ~ObjectB(); 
}; 

#endif /* OBJECTB_H_ */ 

Оба файла .cpp для Objecta и ObjectB пустые (пустой конструктор и деструктор). Вот главный .cpp файл:

#include <iostream> 
using namespace std; 

#include "ObjectA.h" 
#include "ObjectB.h" 

void friendFunction(ObjectA &objA, ObjectB &objB){ 
    cout << "HIIIIIIIIIII"; 
} 

int main() { 
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! 

    return 0; 
} 

Это все, что посылает мне следующее сообщение об ошибке:

'ObjectA' has not been declared 

И эта ошибка указывает на этой линии в ObjectB.h:

friend void friendFunction(ObjectA &, ObjectB &); 

Как вы можете видеть, файл ObjectA.h был включен в файл ObjectB.h. Поэтому я не знаю, откуда моя ошибка.

Возможно, я использую функцию друга неправильно?

Спасибо, ребята!

ответ

2

В ObjectA.h заменить:

#include "ObjectB.h" 

с:

class ObjectB; 

сделать соответствующие изменения в ObjectB.h.

Что происходит, так это то, что main.cpp включает ObjectA.h. Перед объявлением класса ObjectA ObjectA.h включает ObjectB.h. Когда ObjectB.h пытается снова включить ObjectA.h , тест #ifndef OBJECTA_H_ завершился с ошибкой, что означает, что класс ObjectA не объявлен, когда объявлена ​​функция друга, что приводит к ошибке.

Вы можете разбить этот цикл в своем конкретном случае, используя объявление прямого класса вместо #include.

+0

Вы лучший мужчина! – Xema

0

Baybe используя функцию шаблона вместо этого? Но таким образом вы нарушите инкапсуляцию.

class A{ 
private: 
    template<typename T, typename B> 
    friend void friendFunc(const T&, const B&); 
    int m_a; 
}; 

template<typename A, typename B> 
void friendFunc(const A& a, const B& b){ 
    std::cout << a.m_a << std::endl; 
} 

int main(int argc, char **argv) {  
    friendFunc<A, int>(A(), int(3)); 
    return 0; 
}