保持理智的c ++标头

| 我似乎在用c ++进行编码时遇到的最大问题是,必须先声明一个类,然后才能引用它。说我有两个这样的头文件... 头文件1.h
#include \"Header2.h\"
#include <deque>
#include <string>
#include <iostream>
using namespace std;
class HelloPackage;
class Hello
{
public:
    string Message;
    HelloPackage * Package;
    Hello():Message(\"\")
    {

    }
    Hello(string message, HelloPackage * pack)
    {
        Message = message;
        Package = pack;
    }
    void Execute()
    {
        cout << Message << endl;
        //HelloPackage->NothingReally doesn\'t exist.
        //this is the issue essentially
        Package->NothingReally(8);
    }
};
Header2.h
#include \"Header1.h\"
#include <deque>
#include <string>
#include <iostream>
using namespace std;
class HelloPackage
{
public:
    deque<Hello> Hellos;
    HelloPackage()
    {
        Hellos = deque<Hello>();
    }
    int AddHello(string Message)
    {
        Hellos.push_back(Hello(Message,this));
    }
    void ExecuteAll()
    {
        for each(Hello h in Hellos)
            h.Execute();
    }
    int NothingReally(int y)
    {
        int a = 0;
        a += 1;
        return a + y;
    }
}
我想知道的是,有没有解决这些问题的优雅解决方案?在说c#和Java中,您不受此“线性”编译的限制。     
已邀请:
使用标头包含防护,可以使用\“#ifndef / #define / #endif \”或\“#pragma一次\” 将您的代码放在.cpp中,而不是内联在标题中 ??? 利润 之所以适合您,是因为您可以根据需要使用要引用的类的前向声明,而不必包括文件。     
您缺少警卫队 为什么在标头中定义方法? 除了代码中的这些问题外,还要回答您的问题:正常方法是转发声明类-不在标头中包含标头(除非您必须这样做)。     
如果您遵循一些基本规则,那一点都不尴尬。但与例如Java或C#,您必须自己遵循这些规则,编译器和/或语言规范不会强制执行。 其他答案已经指出了这一点,但在这里我将进行概述,以便将您放在一个位置: 使用包括警卫。他们确保您的标头(以及您的类定义)仅被包含一次。 通常,您需要将方法的声明和实现分开。这使标头文件更可重用,并减少了编译时间,因为标头通常比CPP(即实现)文件所需的#include少。 在标题中,使用前向声明而不是包含。仅当您仅使用相应类型的名称,而无需知道任何“内部”时,才有可能。原因是前向声明仅告诉编译器某个名称存在,但不包含其名称。 这是Bar类的前向声明:
class Bar;

class Foo {
    void foooh(Bar * b);
};
在这里,编译器将知道某个地方有一个Bar,但是它不知道它具有什么成员。 仅在CPP文件中使用\“使用命名空间xyz \\”,而不在标头中使用。 好了,这是您的示例代码,经过修改可满足这些规则。我只显示Hello类,因此将HelloPackage相应地分为头文件和CPP文件。 Hello.h(在您的示例中为Header1.h)
#include <string>

class HelloPackage;
class Hello
{
public:
    Hello();
    Hello(std::string message, HelloPackage * pack);
    void Execute();

private:
    string Message;
    HelloPackage * Package;
};
你好
#include \"Hello.h\"

#include \"HelloPackage.h\"

using namespace std;

Hello::Hello() : Message(\"\")
{}

Hello::Hello(string message, HelloPackage * pack)
{
    Message = message;
    Package = pack;
}

void Hello::Execute()
{
    cout << Message << endl;
    // Now accessing NothingReally works!
    Package->NothingReally(8);
}
可能出现的一个问题是,为什么需要包含字符串。您是否也只能向前声明字符串类? 区别在于您将字符串用作嵌入式成员,而不使用指向字符串的指针。可以,但是它会强制您使用#include,因为编译器必须知道字符串实例在Hello类中需要多少空间。     

要回复问题请先登录注册