所以,多亏了这个网站,我找到了我之前问题的答案.我正在向GNU automake项目中的类添加一个函数,该项目使用指向doc对象的指针.依赖被列入Makefile.am文件,包括doc.h与plsa.h在各自的顺序.但是,当我编译时,我会收到doc has not been declared错误.然后,我尝试在这里添加#include语句,这会产生previous redefinition of 'class doc'错误.
我了解到我必须doc使用class doc;下面注释掉的行声明; 但是,我认为只有在我声明一个按值传递对象的函数时才需要这样做.有人可以向我解释为什么#include在这种情况下不正确吗?
#include "doc.h"
//class doc;
class plsa {
// ...
int infer(doc *trset, int maxiter, double noiseH);
}
Run Code Online (Sandbox Code Playgroud)
Alo*_*ave 13
为什么重新定义错误?
请确保您的头文件具有适当的Header Guards/Include Guards.很可能您错过了添加标头保护,因此多次包含标头会导致多个类定义.
在这种情况下,为什么前瞻声明是可以的?
而不是包括头文件,你添加行:
class doc;
Run Code Online (Sandbox Code Playgroud)
它转发声明类doc,这对于编译器来说意味着它是一个不完整类型.对于不完整的类型,我们无法创建它的对象或做任何需要编译器知道布局的事情,doc或者doc只是一个类型的事实.即:编译器不知道它的成员是什么以及它的内存布局是什么.
但由于指向所有对象的指针只需要相同的内存分配,因此只需将不完整类型作为指针进行处理即可使用前向声明.
在这种情况下,doc被引用的唯一方法是指向类的指针doc,因此前向声明也将起作用.
BottomLine:
包含头文件应该适合您如果您有适当的包含防护.它没有任何问题.
但是,由于上面给出的推理,前向声明类也应该对你有用.注意前向声明通常用于存在类的循环依赖性的情况.
哪个更好Include header File还是Forward Declaration?
包括头文件只是复制粘贴从标题到包含文件的位置的代码,这基本上可能导致:
前瞻性声明对如何进一步使用不完整类型有其自身的局限性.
使用不完整类型,您可以:
对于不完整类型,您不能:
鉴于可能性(由于不完整类型使用的上述限制),人们应该更喜欢包含标题的前向声明.
你缺少的包括监护人。如果您只包含刚刚粘贴的文件,则需要确保在多次包含它们时,其他时候代码不会重复。所以你使用这样的构造。
#ifndef _XXX_
#define _XXX_
/* your header here */
#endif
Run Code Online (Sandbox Code Playgroud)