2011-09-18 2 views
2
#include <stdio.h> 
class B; 

class A; 

class A 
{ 
    int a; 
    friend int B::f(); 
}; 


class B 
{ 
    int b; 
    class A x; 
public: 
    int f(); 
}; 

int B::f() 
{ 
    // ... 
} 

main() 
{ 
    class B b; 
    b.f(); 
} 

ОШИБКИ:неполная ошибка типа, при использовании друга функции

a.cpp:9: error: invalid use of incomplete type ‘struct B’ 

a.cpp:2: error: forward declaration of ‘struct B’ 

Проблема не может быть решена путем размещения определения В перед А, как В имеет объект типа А.

Для этот пример делает B класс друга, но в мой реальный код. У меня больше функций-членов в B (так что мне нужно альтернативное решение).

И, наконец, может кто-нибудь дать мне ссылки, которые объясняют, что делает компилятор, когда наступает через декларацию, декларацию, определение.

+0

Проблема в том, что компилятор C++ является «однопроходным», что означает, что он не будет пытаться сохранить то, что он сейчас не может понять, и попытаться решить его позже, когда у него больше информации (в этот пример, о классе B). Почему это все так же, как сейчас, находится вне меня. Во всяком случае, насколько я понимаю, создание B класс друзей A будет работать. Или вы имеете в виду, что вам нужно предоставить доступ к другим функциям участника вне B? – Baltasarq

+0

@Baltasarq: представьте себе тот же фрагмент кода, скомпилированный для чего-то другого, в зависимости от того, что приходит * после *. На каком компилированном языке есть эта функция? – eudoxos

+1

@eudoxos: Java, для одного. Для синтаксиса требуется многопроходный компилятор. И C++ для другого (но только внутри класса). Например, 'class Foo {public: set_item (int val) {item = val;} private: int item;};' –

ответ

2

Определение B Перед A и объявить указатель на A как данные членов B:

class A; //forward declaration 

class B 
{ 
    int b; 
    A *px; //one change here - make it pointer to A 
public: 
    int f(); 

}; 

class A 
{  
    int a; 
    friend int B::f(); 
}; 

Или вы могли бы сделать весь класс B друг A, таким образом, вы не должны введите данные элемента указатель на A.

class B; //forward declaration 

class A 
{  
    int a; 
    friend class B; 
}; 

class B 
{ 
    int b; 
    A x; //No change here 
public: 
    int f(); 

}; 
2

Вы просто не можете делать то, что хотите сделать как есть. Чтобы сделать это объявление функции друга в классе A, характер класса B должен быть известен до определения класса A. Для того чтобы класс B содержал экземпляр класса A, характер класса A должен быть известен до определения класса B. Словить 22.

Первый не применяется, если вы присвоили классу класс B класс класса A. Последнее не применяется, если вы изменяете B, чтобы содержать указатель или ссылку на экземпляр класса A.

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