C++先前的定义错误

发布于 2024-12-12 01:15:23 字数 557 浏览 0 评论 0原文

因此,感谢这个网站,我找到了之前问题的答案。我正在向 GNU automake 项目中的类添加一个函数,该函数使用指向 doc 对象的指针。 Makefile.am 文件中包含依赖项,以按各自的顺序包含 doc.hplsa.h。但是,当我编译时,我会得到一个 doc has not beelated 错误。然后,我尝试在此处添加 #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);
}

So, thanks to this website, I found the answer to my previous problem. I'm adding a function to a class in a GNU automake project that uses a pointer to a doc object. Dependencies were included in the Makefile.am file to include doc.h and plsa.h in the respective order. However, when I compiled, I would get a doc has not been declared error. Then, I tried adding the #include statement here, which gives a previous redefinition of 'class doc' error.

I learned that I have to declare doc by using the class doc; line commented out below; however, I thought that this was only necessary if I was declaring a function that passes the object by value. Can someone explain to me why the #include is incorrect in this case?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌路黄昏 2024-12-19 01:15:23

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

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

class doc;

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

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

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

包含头文件转发声明哪个更好?
包含头文件只是将代码从头文件复制粘贴到包含文件的任何位置,这基本上可能会导致:

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

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

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

对于不完整类型,您不能:

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

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

Why the Redefinition errors?
Please ensure that your header files have appropriate Header Guards/Include Guards.It is most likely that you have missed adding header guards and hence that causes multiple class definitions due to the header getting included multiple times.

Why Forward Declaration is okay in this case?
When instead of including the header file you add the line:

class doc;

It Forward declares the class doc which means for compiler it is an Incomplete type. With Incomplete types, One cannot create objects of it or do anything which needs the compiler to know the layout of docor more than the fact that doc is just an type.
i.e: The compiler does not know what are its members and what its memory layout is.
But Since pointers to all objects need just the same memory allocation, You can use the forward declaration when just reffering to an Incomplete type as a pointer.

In this case the only way in which doc is being referenced is an pointer to the class doc and hence the Forward declaration will work as well.

BottomLine:
Including the header file should work for you If you have proper Inclusion Guards in-place.
And there is nothing wrong with it.
However, Forward declaring the class should also work for you because of the reasoning given above.Note that forward declarations are usually used in case where there is a Circular Dependency of classes.

Which is better Include header File or Forward Declaration?
Including the header file just copy pastes the code from the header to wherever the file was included, which basically could lead to:

  • Increase in compilation time
  • Pollution of global namespace.
  • Potential clash of preprocessor names.
  • Increase in Binary size(in some cases though not always)

Forward Declaration has its own limitations on how the Incomplete type can be used further on.
With Incomplete type you can:

  • Declare a member to be a pointer or a reference to the incomplete type.
  • Declare functions or methods which accepts/return incomplete types.
  • Define functions or methods which accepts/return pointers/references to the incomplete type (but without using its members).

With Incomplete type you cannot:

  • Use it as a base class.
  • Use it to declare a member.
  • Define functions or methods using this type.

Given the possibility(due to above limitations on Incomplete type usage) One should prefer Forward Declaration over Including Header.

眉黛浅 2024-12-19 01:15:23

你缺少的包括监护人。如果您只包含刚刚粘贴的文件,则需要确保在多次包含它们时,其他时候代码不会重复。所以你使用这样的构造。

 #ifndef _XXX_
 #define _XXX_
    /* your header here */
 #endif

You are missing include guardians. if you just include files they are just pasted you need to make sure when they are included multiple times that they other times the code isn't duplicated. so you use a construct like this.

 #ifndef _XXX_
 #define _XXX_
    /* your header here */
 #endif
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文