对内置数据类型使用前向声明
我明白,只要有可能,我们就应该使用前向声明而不是包含来加快编译速度。
我有一个像这样的Person
类。
#pragma once
#include <string>
class Person
{
public:
Person(std::string name, int age);
std::string GetName(void) const;
int GetAge(void) const;
private:
std::string _name;
int _age;
};
和一个像这样的类 Student
#pragma once
#include <string>
class Person;
class Student
{
public:
Student(std::string name, int age, int level = 0);
Student(const Person& person);
std::string GetName(void) const;
int GetAge(void) const;
int GetLevel(void) const;
private:
std::string _name;
int _age;
int _level;
};
在 Student.h 中,我有一个前向声明 class Person;
来在我的转换构造函数中使用 Person
。美好的。但我已经做了 #include
以避免在代码中使用 std::string
时出现编译错误。这里如何使用前向声明来避免编译错误?是否可以?
谢谢。
I understand that wherever possible we shall use forward declarations instead of includes to speed up the compilation.
I have a class Person
like this.
#pragma once
#include <string>
class Person
{
public:
Person(std::string name, int age);
std::string GetName(void) const;
int GetAge(void) const;
private:
std::string _name;
int _age;
};
and a class Student
like this
#pragma once
#include <string>
class Person;
class Student
{
public:
Student(std::string name, int age, int level = 0);
Student(const Person& person);
std::string GetName(void) const;
int GetAge(void) const;
int GetLevel(void) const;
private:
std::string _name;
int _age;
int _level;
};
In Student.h, I have a forward declaration class Person;
to use Person
in my conversion constructor. Fine. But I have done #include <string>
to avoid compilation error while using std::string
in the code. How to use forward declaration here to avoid the compilation error? Is it possible?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用
string
作为由于需要
string
的整体结构,因此必须需要声明。您必须#include
。如果您编写的话,可以省略
string
的声明,例如您可以使用前向声明,但我仍然建议您不要这样做,因为
std: :string
不是像 Person 或 Student 这样的简单结构类型,而是一个非常复杂的类型,涉及很多模板:如果你向前声明错误(例如
class string;
),编译将失败当您因类型冲突而实际使用它时。Since used
string
asthe whole structure of
string
would be needed, so the declaration must be needed. You must#include <string>
.Declaration of
string
can be omitted possible if you write, e.g.which you could use a forward declaration, but I still recommend you not to do so, because
std::string
is not a simple structure type like Person or Student, but a very complex type involving many templates:If you forward declare it wrongly (e.g.
class string;
), the compilation will fail when you actually use it because of conflicting type.您只能将前向声明与指针和引用一起使用(因为它们具有固定大小,与它们引用的对象的大小无关)。如果按值使用特定类,编译器需要其完整定义(以便知道其确切大小),因此前向声明是不够的。
因此,如果您像这样定义
Student
,上述任一类成员都会强制您在标头中添加
#include
Person.h。您很清楚,前向声明有助于避免编译依赖,从而减少编译时间。然而,这主要涉及用户定义的标头,因为这些标头可能会经常更改。标准库头不会改变,因此在这些情况下节省并不重要。
You can only use forward declarations with pointers and references (because these are of a fixed size, independent of the size of the object they refer to). If you use a specific class by value, the compiler needs its full definition (in order to know its exact size), thus forward declaration is not enough.
Thus, if you define
Student
like thiseither of the above class members would force you to
#include
Person.h in your header.You understand well, that forward declaration helps avoiding compilation dependencies, thus reduces compilation time. However, that concerns mainly user-defined headers, because these are the ones that can change frequently. Standard library headers are not going to change, so the saving is not significant in those cases.
您只能使用前向声明进行类型标识,例如在函数/方法指针参数原型中使用声明的类型时。如果您要声明一个成员变量(即 std::string _name;),编译器需要的内容比前向声明所能提供的要多一些。例如,如果有人执行 sizeof(Student) ,则编译器必须有权访问整个声明才能计算出大小。
You can only use forward declarations for type identification, such as when you use the declared type in a function/method pointer parameter prototype. If you are going to declare a member variable (i.e. std::string _name;) the compiler needs a little bit more than a forward declaration can give it. For example, if someone does a sizeof(Student) the compiler has to have access to the entire declaration to figure out the size.
也许还可以考虑使用继承。
Maybe also consider to use inheritance.
前向声明用于减少包含并解决循环依赖关系。但是,当在类的公共或受保护接口中使用转发时,您需要将包含正确头文件的负担交给类的用户。;字符串;。使用
除此之外,STL 中定义的转发类型可能无法按预期工作。例如,std::string 可以定义为 typedef basic_string
namespace std{ class string;}
向前声明它会给你一个编译错误。Forward declarations are used to reduce include and to resolve cyclic dependencies. But when using forwards in the public or protected interface of your class, you place the burden of including the correct header files to the users of your class.
Beside this, forwarding types defined in the STL may not work as expected. For example, std::string might be defined as
typedef basic_string<char> string;
. Declaring it forward withnamespace std{ class string;}
will give you a compilation error.