прямое объявление в двух заголовках и двух файлах cpp

У меня есть четыре файла C ++, два заголовка и два cpp. Заголовки должным образом охраняются, и в первом я использую предварительное объявление, подобное этому:

//A.h
class B;

class A {
public:
A();
void doSomething(B* b);
};

и некоторая реализация:

void A::doSomething(B* b){
b->add();
}

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

#include "A.h"class B {
public:
B();
void add();
};

а также

void B::add(){
cout << "B is adding" << endl;
}

Я получаю сообщение об ошибке «Доступ участника к неполному типу B», и я застрял там. Мне нужно использовать a B в A, и каждый B должен иметь указатель на своего «владельца», экземпляр A. Что я могу сделать, чтобы решить эту ситуацию.

заранее спасибо

1

Решение

B.cpp Файл, несмотря на то, что назван аналогично, не включает в себя B.h, Вы должны включить B.h из обеих реализаций. Кроме того, если вы хотите включить и то и другое A.h а также B.hсоздать включать охранников

0

Другие решения

решил проблему, используя предварительные объявления в определениях классов (A и B) (заголовки) и включив A.h в B.cpp, а также B.h в A.cpp. Вот код:

//A.h

#ifndef A_H_
#define A_H_

#include <iostream>

using namespace std;

class B;

class A{
public:
A();
virtual ~A();

private:
B* pToB;

public:
void doSomething(B* b);
void SetB(B* b);
};

#endif

Cpp для класса A, обратите внимание на включение B.h (это я бы обычно не делал)

// A.cpp

#include "A.h"#include "B.h"
A::A():pToB(){
cout << "A constructor" << endl;
}

A::~A(){}

void A::SetB(B* b){
this->pToB = b;
cout << "setting B" << endl;
}

void A::doSomething(B* b){
cout << "A is gonna call B's method add: ";
b->add();
}

теперь класс B:

// B.h

#ifndef B_H_
#define B_H_

#include <iostream>

using namespace std;

class A;

class B{
public:
B();
virtual ~B();

private:
A* pToA;

public:
void add();
void SetA(A* a);
};

#endif

реализация для B

// B.cpp

#include "B.h"#include "A.h"
B::B():pToA(){
cout << "B constructor” << endl;
}

B::~B(){}

void B::SetA(A* a){
this->pToA = a;
cout << "setting A" << endl;
}

void B::add(){
cout << "B is adding" << endl;
}

cpp включая основную функцию (оба заголовка включены, не включены)

#include "A.h"#include "A.h"
int main() {
A* newA = new A;
B* newB = new B;
newA->SetB(newB);
newB->SetA(newA);
newA->doSomething(newB);
return 0;
}

вывод для этой программы выглядит так:

A constructor
B constructor
setting B
setting A
A is gonna call B's method add: B is adding

благодаря Сандип Датта чья решение помог мне решить эту проблему

0

Вам нужно иметь определение для класса B, прежде чем вы сможете использовать doSomething(B* b) метод, поэтому я думаю вместо:

class B;

class A {
public:
A();
void doSomething(B* b);
};

вам нужно будет сделать что-то вроде:

class B;

class A {
public:
A();
};

void A::doSomething(B* b);

объявив его после этого, компилятор получит необходимую информацию о классе B (распределение памяти и т. д.).

-1