我正在尝试用c ++编写一个简单的程序,我有2个类,两个都可以互相访问函数。这是我最终想要做的事情的简化,即创建一个带有棋盘和棋子类的游戏。我能够在java中做到这一点,但我现在遇到的问题是尝试在c ++中做同样的事情。我的代码如下:
#include <iostream>
class B;
class A {
public:
void sync(B obj){
b = obj;
}
void print(){
std::cout << "Hello from class A" << std::endl;
}
void printBoth(){
std::cout << "Hello from class A" << std::endl;
b.print();
}
private:
B b;
};
class B {
public:
B(A obj){
a = obj;
}
void print(){
std::cout << "Hello from class B" << std::endl;
}
void printBoth(){
std::cout << "Hello from class B" << std::endl;
a.print();
}
private:
A a;
};
int main(){
A a;
B b(a);
a.sync(b);
a.printBoth();
std::cout << std::endl;
b.printBoth();
return 0;
}
当我尝试使用g++ example.cpp
编译时,我收到5个错误:
example.cpp:20:5: error: field ‘b’ has incomplete type
B b;
^
example.cpp: In member function ‘void A::sync(B)’:
example.cpp:7:8: error: ‘obj’ has incomplete type
void sync(B obj){
^
example.cpp:3:7: error: forward declaration of ‘class B’
class B;
^
example.cpp:8:4: error: ‘b’ was not declared in this scope
b = obj;
^
example.cpp: In member function ‘void A::printBoth()’:
example.cpp:17:4: error: ‘b’ was not declared in this scope
b.print();
^
我从来没有在课堂上使用过前声明,所以如果我遗漏了一些明显的东西,我会道歉。感谢任何帮助,我提前感谢你。
答案 0 :(得分:1)
您的代码存在两个问题。
让我们先解决第一个问题。
这是两个类的示例,其中的方法相互调用。相当无意义,并导致无限循环,但这演示了前向声明的一般原则,您可以将其用作模板来修复您显示的代码。
class A {
public:
void foo();
};
class B {
public:
void foo();
};
void A::foo()
{
B b;
b.foo();
}
void B::foo()
{
A a;
a.foo();
};
现在,您的代码存在第二个问题:
如上所述,你的类A包含一个B类实例,它包含一个A类实例,它包含一个A类实例,它包含一个B类实例,一直到宇宙崩溃为一个大规模黑洞。我只想说,这不会编译。
C ++对象与Java对象根本不同。他们以完全不同的方式工作。您可以在Java中执行此操作,因为脏的小秘密是Java中的所有对象实际上都是海市蜃楼,它们实际上是指向实际对象的引用计数指针。在C ++中,与此最接近的是向对象声明std::shared_ptr
:
#include <memory>
class A;
class B;
class A {
// ...
private:
std::shared_ptr<B> b;
};
class B {
// ...
private:
std:shared_ptr<A> a;
};
这将是您显示的代码的第二个问题。通常,在学习C ++对象时,您需要完全忘记Java对象的所有知识。它们根本不同,并且试图在您已经了解的Java对象和C ++对象之间进行类比,只会导致混淆。
答案 1 :(得分:1)
您可以随时尝试重新设计,即:
#include <iostream>
#include "A.hpp"
int main(){
A a;
B b(a);
a.sync(b);
a.printBoth();
std::cout << std::endl;
b.printBoth();
return 0;
}
B.hpp:
class A;
class B {
public:
B() {}
B(A obj);
void print();
void printBoth();
private:
A* a;
};
B.cpp:
#include <iostream>
#include "A.hpp"
B::B(A obj){
a = new A(obj);
}
void B::print(){
std::cout << "Hello from class B" << std::endl;
}
void B::printBoth(){
std::cout << "Hello from class B" << std::endl;
a->print();
}
A.hpp:
#include "B.hpp"
class A {
public:
void sync(B obj);
void print();
void printBoth();
private:
B b;
};
A.cpp:
#include <iostream>
#include "A.hpp"
void A::sync(B obj){
b = obj;
}
void A::print(){
std::cout << "Hello from class A" << std::endl;
}
void A::printBoth(){
std::cout << "Hello from class A" << std::endl;
b.print();
}