C++ 在头文件中正确使用声明对象

C++ 在头文件中正确使用声明对象,c++,object,header,C++,Object,Header,我正在做一个时钟显示作业,我的教授希望我们使用两个类,数字显示和时钟显示。所以我总共有两个头文件和三个cpp文件。当我使用第一个类实现作业的第一部分时,一切都很好。不过我注意到,我的教授希望我们在ClockDisplay标题中声明一个NumberDisplay对象。我想只要像普通人一样声明就会像这样工作NumberDisplay hours=NumberDisplay(24)但是,除非我为我的ClockDisplay.h包含NumberDisplay.h文件,否则我无法访问该信息。然而,当我这样

我正在做一个时钟显示作业,我的教授希望我们使用两个类,数字显示和时钟显示。所以我总共有两个头文件和三个cpp文件。当我使用第一个类实现作业的第一部分时,一切都很好。不过我注意到,我的教授希望我们在ClockDisplay标题中声明一个NumberDisplay对象。我想只要像普通人一样声明就会像这样工作
NumberDisplay hours=NumberDisplay(24)但是,除非我为我的ClockDisplay.h包含NumberDisplay.h文件,否则我无法访问该信息。然而,当我这样做时,我假设我的错误是由于在我的
NumberDisplay.cpp
和我的
ClockDisplay.cpp
中使用了
。我只是想知道构造文件的正确方法,以便我可以在我的ClockDisplay头文件中正确创建NumberDisplay对象,然后在我的ClockDisplay cpp文件中使用这些对象。

您可以
ClockDisplay.h
中包含“NumberDisplay.h”
。这将允许您在ClockDisplay的类声明中使用NumberDisplay对象

作为旁注,请确保对标题使用“包含防护”。这将防止在编译过程中多次包含标头。使用
#pragma一次

#ifndef NUMBERDISPLAY_H_
#define NUMBERDISPLAY_H_
...
#endif // NUMBERDISPLAY_H_

正如用户肖恩·门罗(Sean Monroe)所指出的,关于使用
标题
包含警卫
;这可能并不总是完整的答案。在许多情况下,这将有助于解决您当前的问题,但如果您不小心,您可能会成为循环包含的受害者

在提到这一点之前,我将简要描述
#include
#include“someheader.h”
之间的区别。第一个将通过使用默认情况下通过IDE设置的系统环境变量,查看大多数系统、操作系统、编译器和标准库文件的位置。后者将查找在当前项目的include路径中设置的任何直接目录,根路径是在Visual Studio中创建代码时代码所在的位置;其他IDE很可能会有所不同,但概念仍然相同

在通告中包括:有时仅仅有头球护卫是不够的。例如:

文件a.h

文件b.h

在这里,这将生成一个循环include,这是非常重要的。无论您尝试在其他文件、命名空间或,类或函数编译器将尝试构造第一个类,为此它需要构造第二个类。然而,当试图构造第二个类来完成第一个类时,它会返回并尝试再次构造第一个类,因为下一个类需要第一个类,而第一个类是不完整的对象,反之亦然。这并不完全是一个循环包含,但它是不完整类依赖项的循环无限递归。您可以阅读此Q/A以了解更多信息:

有时仅仅将一个类的适当头包含到另一个类的头中是不够的;有时您可能需要在类的头中声明
类原型
和/或
转发声明
,然后将头文件包含在该类的
cpp
文件中。但这通常适用于
指针
引用
,但不适用于本地副本,因为
指针
引用
由内存中具有固定大小的内存位置寻址。例如:

文件A.h

文件A.cpp

文件B.h


这里的问题比这里讨论的要多,但是你可以在我上面提供的同一链接的其他一些答案中了解到这些问题。

我不确定是否能找到更好的目标,相关的/重复的:你几乎可以把声明放在任何地方,问题是
NumberDisplay hours=NumberDisplay(24)
也是一个定义您是否建议只在标题中声明,并可能在以后的cpp中定义它?尝试在当前状态下构建它时,我会遇到很多错误,从这一个开始
错误C3646:“小时”:未知覆盖说明符
移动到
,包括“NumberDisplay.h”到
时钟显示,看来问题已经解决了。非常感谢。
#ifndef A_H
#define A_H

#include "b.h"

class A {
private:
    B b;
public:
    explicit A( const B& b ) { ... }
};

#endif
#ifndef B_H
#define B_H

#include "A.h"

class B {
public:
    explicit( A* pA ) { ... }
};

#endif
#ifndef A_H
#define A_H

class B;

class A {
private:
    B* pB;
public:
    explicit A( const B& b );
}; 

#endif
#include "A.h"
#include "B.h"

A::A( const B& b ) { ... }
#ifndef B_H
#define B_H

#include "A.h"

class B {
public:
    B(){ ... }

    /*param type*/ someFunc( A* pA ) { /* do something with pA */ }
};