C++先前的定义错误
因此,感谢这个网站,我找到了之前问题的答案。我正在向 GNU automake 项目中的类添加一个函数,该函数使用指向 doc 对象的指针。 Makefile.am 文件中包含依赖项,以按各自的顺序包含 doc.h
和 plsa.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么会出现重新定义错误?
请确保您的标头文件具有适当的标头防护/包含防护。您很可能错过了添加标头防护,因此由于多次包含标头而导致多个类定义。
为什么在这种情况下可以进行前向声明?
当不包含头文件时,您添加以下行:
它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:
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 ofdoc
or more than the fact thatdoc
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 classdoc
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
orForward Declaration
?Including the header file just copy pastes the code from the header to wherever the file was included, which basically could lead to:
Forward Declaration has its own limitations on how the Incomplete type can be used further on.
With Incomplete type you can:
With Incomplete type you cannot:
Given the possibility(due to above limitations on Incomplete type usage) One should prefer Forward Declaration over Including Header.
你缺少的包括监护人。如果您只包含刚刚粘贴的文件,则需要确保在多次包含它们时,其他时候代码不会重复。所以你使用这样的构造。
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.