保持理智的c ++标头

如何解决保持理智的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类中需要多少空间。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?