如何解决保持理智的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 举报,一经查实,本站将立刻删除。