Предварительное объявление с функцией друга: недопустимое использование неполного типа

#include <iostream>

class B;

class A{
 int a;
public:
 friend void B::frndA();
};

class B{
 int b;
public:
 void frndA();
};

void B::frndA(){
 A obj;
 std::cout << "A.a = " << obj.a << std::endl;
}

int main() {
 return 0;
}

При попытке скомпилировать этот код возникли некоторые ошибки. Например.

недопустимое использование неполного типа

Какие проблемы в этом коде?


person Arif    schedule 06.07.2010    source источник
comment
Я повторно пометил вопрос. friend не самое полезное ключевое слово. Также forward-declaration имеет больше смысла при объединении в один тег. Редактировать: О, и class также имеет больше смысла, чем function, я думаю :)   -  person Ivo Wetzel    schedule 06.07.2010


Ответы (3)


Поместите всю декларацию class B ... перед class A. Вы еще не объявили B::frndA();.

#include <iostream>
using namespace std;

class B{
    int b;
public:
    void frndA();
};

class A{
    int a;
public:
    friend void B::frndA();
};



void B::frndA(){
    A obj;
    //cout<<"A.a = "<<obj.a<<endl;
}

int main() {
    return 0;
}
person Anthony    schedule 06.07.2010

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

Вам нужно будет изменить свой код, чтобы решить проблему (т.е. переместить определение class B перед class A).

person R Samuel Klatchko    schedule 06.07.2010

Вам нужно поместить объявление B перед A. Компилятор об этом не знает: B::frndA(). Предварительного объявления недостаточно информации, чтобы сделать вывод о том, какие члены имеет тип.

Я бы рекомендовал поместить объявление вашего класса A в файл A.h, а его определение — в файл A.cpp. Аналогично для типа B внутри B.h и B.cpp

В начале каждого заголовочного файла поставьте #pragma once (или, если хотите, включите защиту).

Затем внутри вашего B.h вы можете просто включить A.h.

person Brian R. Bondy    schedule 06.07.2010
comment
Фактически, pragma Once может дать сбой, если один и тот же файл попадает в разные пути поиска, поскольку он основан на пути, а не на содержимом файла. - person Edward Strange; 06.07.2010
comment
pragma Once поддерживается всеми основными компиляторами. Я не думаю, что #pragma Once заслуживает отрицательного голосования. См. здесь: stackoverflow.com/questions/ 1143936/ - person Brian R. Bondy; 06.07.2010