gpt4 book ai didi

C++ 先前定义错误

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:56:48 24 4
gpt4 key购买 nike

所以,感谢这个网站,我找到了我之前问题的答案。我正在向 GNU automake 项目中的类添加一个函数,该项目使用指向 doc 对象的指针。依赖项包含在 Makefile.am 文件中,以按各自的顺序包含 doc.hplsa.h。但是,当我编译时,我会得到一个 doc has not been declared 错误。然后,我尝试在此处添加 #include 语句,它给出了 previous redefinition of 'class doc' 错误。

我了解到我必须使用下面注释掉的 class doc; 行来声明 doc;但是,我认为只有在声明按值传递对象的函数时才需要这样做。有人可以向我解释为什么 #include 在这种情况下不正确吗?

#include "doc.h"
//class doc;
class plsa {
// ...
int infer(doc *trset, int maxiter, double noiseH);
}

最佳答案

为什么会出现重定义错误?
请确保您的头文件具有适当的 Header Guards/Include Guards 。您很可能错过了添加 header 保护,因此由于多次包含 header 而导致多个类定义。

为什么前向声明在这种情况下可以?
当您添加行而不是包含头文件时:

class doc;

Forward 声明 doc 类,这对编译器来说意味着它是一个不完整类型。对于 Incomplete 类型,人们无法创建它的对象或做任何需要编译器知道 doc 布局的事情,或者除了 doc 只是一种类型这一事实之外。即:编译器不知道它的成员是什么以及它的内存布局是什么。
但是由于指向所有对象的指针只需要相同的内存分配,因此当仅引用不完整类型作为指针时,您可以使用前向声明。

在这种情况下,引用 doc 的唯一方法是指向类 doc 的指针,因此 Forward 声明也将起作用。

底线:
如果您有适当的 Inclusion Guards,那么包含头文件应该对您有用。而且没有任何问题。
但是,由于上面给出的推理,前向声明类也应该对您有用。请注意,前向声明通常用于类的循环依赖的情况。

Include header FileForward Declaration 哪个更好?
包含头文件只是将头文件中的代码复制粘贴到包含文件的任何位置,这基本上可能导致:

  • 增加编译时间
  • 全局命名空间的污染。
  • 预处理器名称的潜在冲突。
  • 二进制大小增加(在某些情况下但并非总是如此)

前向声明对于如何进一步使用 Incomplete 类型有其自身的限制。
使用不完整类型,您可以:

  • 将成员声明为指针或对不完整类型的引用。
  • 声明接受/返回不完整类型的函数或方法。
  • 定义接受/返回指向不完整类型的指针/引用的函数或方法(但不使用其成员)。

对于 Incomplete 类型,您不能:

  • 将其用作基类。
  • 用它来声明一个成员。
  • 使用此类型定义函数或方法。

考虑到这种可能性(由于上述对不完整类型使用的限制)人们应该更喜欢前向声明而不是包含 header 。

关于C++ 先前定义错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7919600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com