Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何跨文件C++; 我一直在试图解决如何在C++中跨多个文件声明类。我能在两个班上成功地做到这一点,但在许多班上都这么做让我感到困惑。我尝试在头文件中声明所有类,并将其包含在所有类中,但我得到了不完整类的错误。我仔细研究了一下,但所有的解决方案似乎都不合理或让我困惑。你能解释一下做这件事的好方法吗_C++_Class - Fatal编程技术网

如何跨文件C++; 我一直在试图解决如何在C++中跨多个文件声明类。我能在两个班上成功地做到这一点,但在许多班上都这么做让我感到困惑。我尝试在头文件中声明所有类,并将其包含在所有类中,但我得到了不完整类的错误。我仔细研究了一下,但所有的解决方案似乎都不合理或让我困惑。你能解释一下做这件事的好方法吗

如何跨文件C++; 我一直在试图解决如何在C++中跨多个文件声明类。我能在两个班上成功地做到这一点,但在许多班上都这么做让我感到困惑。我尝试在头文件中声明所有类,并将其包含在所有类中,但我得到了不完整类的错误。我仔细研究了一下,但所有的解决方案似乎都不合理或让我困惑。你能解释一下做这件事的好方法吗,c++,class,C++,Class,如果有帮助,这里有一些具体发生的问题的示例代码。类A包含在类C中,但类A也包含类B,该类包含类C,导致错误,因为类C尚未声明 类转发声明 //Tried "Class Name {};" but that also failed Class A; Class B; Class C; 甲级 //Class A #include "B.h" class A{ private: B b; public: void SetBInt(int set) {b.SetInt(set);} }

如果有帮助,这里有一些具体发生的问题的示例代码。类A包含在类C中,但类A也包含类B,该类包含类C,导致错误,因为类C尚未声明

类转发声明

//Tried "Class Name {};" but that also failed
Class A;
Class B;
Class C;
甲级

//Class A
#include "B.h"

class A{
 private:
  B b;
 public:
  void SetBInt(int set) {b.SetInt(set);}
}
B类

//Class B
#include "C.h"
class B{
 private:
  C c;
  int i = 0;
 public:
  void SetInt(int set){i = set;}
}
C类

//Class C
#include "A.h"
class C{
 private:
  int i = 0;
 public:
  void SetInt(int set){i = set;}
}

您必须避免循环依赖关系。避免它们的一种常见方法是预先声明类型,并且在头中不包含该类型的任何实例或函数调用

您可以通过将实例(如
B
)更改为引用或指针来实现这一点:
B*B
。您还必须将使用
b
的任何代码移动到CPP文件中,以便在使用之前可以
#包括“b.h”

例如,代替

// we'll remove this header's dependency on B shortly
#include "B.h"

class A
{
  B b;
public:
  A() { b.SetInt(0); }
};
你可以这样做:

class B;

class A
{
  B *b; // *pointers and &references to a predeclared class are fine.
public:
  A();
  ~A();
};
。。。然后在A.cpp中:

#include "A.h" // ALWAYS include your own header first
#include "B.h"

A::A()
{
  // we didn't need to know how big B was until now, when we're about to make one and
  // run its constructor.  We'll also need to know what functions are available, and the
  // types of all its parameters (or lack of parameters).
  b = new B();
  b->SetInt(0);
}

A::~A()
{
  delete b; // for every "new" there must be a "delete"
}
是的,如果使用
std::unique_ptr b
而不是原始指针,这会(更好)。使用智能指针,我们不需要显式析构函数。我只是不想对仍在学习的人扔太多潜在的新东西


或者,您可以将引用传递到构造函数中,并使用成员初始值设定项列表(您只能在构造引用时设置引用)。这就产生了“对象生存期”问题。如果您在构造时传入的B实例在A使用它之前被破坏,那么您的程序将在下次使用它时严重崩溃(如果您幸运的话:这样您就可以很好地了解问题所在)。最好在你有更多的经验之前避免这种情况。

你有一种似乎不必要的循环依赖。为什么
C.h
需要包含
A.h
?“类A包含在类C中”-这与您给出的示例不匹配。请注意,正向声明仅对指针和引用类型有帮助。如果您的类持有指向另一个类型的非指针/引用,则前向声明不会解决您的问题,因为编译器必须知道类型的大小才能确定类的内存布局。循环依赖关系很棘手,细节也很重要。请让您发布的代码反映您的实际代码,否则我们都在浪费时间。关系A包括B,B包括C,C包括A是不可行的,除非您使用指针或引用。你想在这里实现什么?谢谢你的帮助,到目前为止它已经解决了这个问题!