我可以在 header 文件中的其他 header 中定义 forward-declare 名称吗?
Can I forward-declare names -defined in other header in a header files?
我想创建一个 class Student
,它具有类型库 std::string
的成员,但我不想包含 header <string>
在我的 Student.h
中只使用 forward-declaration:
// Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
typedef class string_ string;
struct Student
{
public:
Student(const string_&, std::size_t);
const string_ name()const;
void setName(const string_&);
std::size_t age()const;
void setAge(std::size_t);
private:
string_* name_ ;
std::size_t age_;
};
// Student.cpp
#include "Student.h"
#include <string>
Student::Student(const std::string& str, std::size_t a) :
name_(&str),
age_(a)
{}
当我编译程序时出现这些错误:../src/Student.cpp:13:2: error: no declaration matches ‘Student::Student(const string&, std::size_t)’
13 | Student::Student(const std::string& str, std::size_t a) :
所以我可以使用前向声明以便在 header 中我不包含任何 header 但只包含 forward-declare 我需要的类型然后在来源我包括 headers?
我这样做是因为我正在阅读 Guillaume Lazar 的《精通 Qt5》一书,他在书中给出了这个例子:
//SysInfoWindowsImpl.h
#include <QtGlobal>
#include <QVector>
#include "SysInfo.h"
typedef struct _FILETIME FILETIME;
class SysInfoWindowsImpl : public SysInfo
{
public:
SysInfoWindowsImpl();
void init() override;
double cpuLoadAverage() override;
double memoryUsed() override;
private:
QVector<qulonglong> cpuRawData();
qulonglong convertFileTime(const FILETIME& filetime) const;
private:
QVector<qulonglong> mCpuLoadLastValues;
};
//SysInfoWindowsImpl.cpp
#include "SysInfoWindowsImpl.h"
#include <windows.h>
SysInfoWindowsImpl::SysInfoWindowsImpl() :
SysInfo(),
mCpuLoadLastValues()
{
}
void SysInfoWindowsImpl::init()
{
mCpuLoadLastValues = cpuRawData();
}
qulonglong SysInfoWindowsImpl::convertFileTime(const FILETIME& filetime) const
{
ULARGE_INTEGER largeInteger;
largeInteger.LowPart = filetime.dwLowDateTime;
largeInteger.HighPart = filetime.dwHighDateTime;
return largeInteger.QuadPart;
}
”语法typedef struct _FILETIME FILETIME
是一种向前
FILENAME 语法的声明。由于我们只使用参考,我们可以避免
在我们的文件 SysInfoWindowsImpl.h 中包含标签并保留它
在 CPP 文件中。”来自书中。
- 所以有人可以向我解释他如何使用
windows.h
中定义的 typedef struct _FILETIME
吗?谢谢。
不,你不能在今天(2020 年 5 月)。另见 this and n3337(C++11 标准)。
但 C++20 或更高版本可能会添加 modules,然后情况就不同了。
实际上,对于一个小程序(例如少于几万行你的 C++ 代码)一个常见的方法是有一个头文件 - 你会#include
在你的每个translation units, and that common master header file would #include
many standard headers. With recent GCC, you could use precompiled headers (and practically speaking, that works the best with a single master header, perhaps #include
-ing sub header files; see this解释中)
考虑使用足够好的 build automation toolset. On Linux, that might be a combination of GCC or Clang, ccache, with make or ninja,等等...
是的,但前提是它们匹配。
您转发声明了 全局 类型 string
,不在命名空间 std
.
中
你或许可以让它与 namespace std {}
一起工作,但是你的程序会有未定义的行为,因为你不允许在该命名空间中声明新的东西(除了少数例外)。
一般来说,除了您自己的 类。
,您希望避免对任何内容进行前向声明
就#include <string>
。如果这样做导致问题,您应该独立解决这些问题。
我想创建一个 class Student
,它具有类型库 std::string
的成员,但我不想包含 header <string>
在我的 Student.h
中只使用 forward-declaration:
// Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
typedef class string_ string;
struct Student
{
public:
Student(const string_&, std::size_t);
const string_ name()const;
void setName(const string_&);
std::size_t age()const;
void setAge(std::size_t);
private:
string_* name_ ;
std::size_t age_;
};
// Student.cpp
#include "Student.h"
#include <string>
Student::Student(const std::string& str, std::size_t a) :
name_(&str),
age_(a)
{}
当我编译程序时出现这些错误:
../src/Student.cpp:13:2: error: no declaration matches ‘Student::Student(const string&, std::size_t)’ 13 | Student::Student(const std::string& str, std::size_t a) :
所以我可以使用前向声明以便在 header 中我不包含任何 header 但只包含 forward-declare 我需要的类型然后在来源我包括 headers?
我这样做是因为我正在阅读 Guillaume Lazar 的《精通 Qt5》一书,他在书中给出了这个例子:
//SysInfoWindowsImpl.h #include <QtGlobal> #include <QVector> #include "SysInfo.h" typedef struct _FILETIME FILETIME; class SysInfoWindowsImpl : public SysInfo { public: SysInfoWindowsImpl(); void init() override; double cpuLoadAverage() override; double memoryUsed() override; private: QVector<qulonglong> cpuRawData(); qulonglong convertFileTime(const FILETIME& filetime) const; private: QVector<qulonglong> mCpuLoadLastValues; }; //SysInfoWindowsImpl.cpp #include "SysInfoWindowsImpl.h" #include <windows.h> SysInfoWindowsImpl::SysInfoWindowsImpl() : SysInfo(), mCpuLoadLastValues() { } void SysInfoWindowsImpl::init() { mCpuLoadLastValues = cpuRawData(); } qulonglong SysInfoWindowsImpl::convertFileTime(const FILETIME& filetime) const { ULARGE_INTEGER largeInteger; largeInteger.LowPart = filetime.dwLowDateTime; largeInteger.HighPart = filetime.dwHighDateTime; return largeInteger.QuadPart; }
”语法typedef struct _FILETIME FILETIME
是一种向前
FILENAME 语法的声明。由于我们只使用参考,我们可以避免
在我们的文件 SysInfoWindowsImpl.h 中包含标签并保留它
在 CPP 文件中。”来自书中。
- 所以有人可以向我解释他如何使用
windows.h
中定义的typedef struct _FILETIME
吗?谢谢。
不,你不能在今天(2020 年 5 月)。另见 this and n3337(C++11 标准)。
但 C++20 或更高版本可能会添加 modules,然后情况就不同了。
实际上,对于一个小程序(例如少于几万行你的 C++ 代码)一个常见的方法是有一个头文件 - 你会#include
在你的每个translation units, and that common master header file would #include
many standard headers. With recent GCC, you could use precompiled headers (and practically speaking, that works the best with a single master header, perhaps #include
-ing sub header files; see this解释中)
考虑使用足够好的 build automation toolset. On Linux, that might be a combination of GCC or Clang, ccache, with make or ninja,等等...
是的,但前提是它们匹配。
您转发声明了 全局 类型 string
,不在命名空间 std
.
你或许可以让它与 namespace std {}
一起工作,但是你的程序会有未定义的行为,因为你不允许在该命名空间中声明新的东西(除了少数例外)。
一般来说,除了您自己的 类。
,您希望避免对任何内容进行前向声明就#include <string>
。如果这样做导致问题,您应该独立解决这些问题。