我可以在头文件中向前声明在其他头文件中定义的名称吗?

问题描述 投票:0回答:1

我想创建一个类 Student 的成员类型为库的 std::string 但我不想在其中加入头像。<string> 在我 Student.h 并只使用正向声明。

// 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) :

  • 所以我可以使用forward声明,这样在头文件中我就不包含任何头文件,而只对我需要的类型进行forward声明,然后在源代码中包含头文件?

  • 我这样做是因为我正在阅读Guillaume Lazar的Mastering 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语法的一种forwarddeclaration。由于我们只使用了一个引用,所以我们可以避免在我们的文件SysInfoWindowsImpl.h中包含这个标签,而将其保留在CPP文件中。"从书中可以看出。

  • 那么谁能给我解释一下,他怎么能用 typedef struct _FILETIME 其定义为 windows.h? 谢谢你,我想创建一个学生类,它的成员类型是库中的std::string,但我不想包含头。
c++ forward-declaration
1个回答
3
投票

是的,但只有在它们匹配的情况下。

你向前声明了一个 全球性 类型 string,不在命名空间 std.

你也许可以让它与 namespace std {} 但这样你的程序就会有未定义的行为,因为你不允许在那个命名空间中声明新的东西(除了少数例外)。

一般来说,除了你自己的类之外,你要避免对任何东西进行前向声明。

只要 #include <string>. 如果这样做会造成问题,你应该独立解决这些问题。


0
投票

不,你不能在今天(2020年5月)。另见 这个n3337 (C++11标准)。

但C++20或更高版本可能会增加 模块,然后事情就变得不一样了。

实际上,对于一个小程序(例如,少于几万行的程序)来说,如果是一个小程序(例如,少于几万行的程序),那么就会有不同的结果。你的 C++代码)一个常见的方法是有一个单一的头文件--它的内容是 #include 在你们每个 翻译单位。 而这个共同的主文件将是 #include 许多标准头。随着最近 海湾合作委员会,你可以使用 预编页眉 (实际上,这对单一的主头来说效果最好,也许是...)。#include -子头文件;见 这个 解释)

也可以考虑使用足够好的 建立自动化 工具集。在Linux上,这可能是下列工具的组合 海湾合作委员会铛铛, ccache,与 使忍者,等等....

© www.soinside.com 2019 - 2024. All rights reserved.