У меня есть четыре файла 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. Что я могу сделать, чтобы решить эту ситуацию.
заранее спасибо
B.cpp
Файл, несмотря на то, что назван аналогично, не включает в себя B.h
, Вы должны включить B.h
из обеих реализаций. Кроме того, если вы хотите включить и то и другое A.h
а также B.h
создать включать охранников
решил проблему, используя предварительные объявления в определениях классов (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
благодаря Сандип Датта чья решение помог мне решить эту проблему
Вам нужно иметь определение для класса 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 (распределение памяти и т. д.).