Reputation: 2552
I want to create a class Student
that has a member of type library std::string
but I don't want to include the header <string>
in my Student.h
and use only 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)
{}
When I compile the program I get these errors: ../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) :
So can I use forward declaration so that in a header I don't include any header but just forward-declare for the types I need then in source I include the headers?
I've done this because I'm reading Mastering Qt5 book by Guillaume Lazar in which he gave this example:
//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;
}
"The syntax typedef struct _FILETIME FILETIME
is a kind of forward
declaration for FILENAME syntax. As we only use a reference, we can avoid
including the tag in our file SysInfoWindowsImpl.h and keep it
in the CPP file." from the book.
typedef struct _FILETIME
which is defined in windows.h
? Thank you.Upvotes: 0
Views: 307
Reputation: 1
No, you cannot today (in may 2020). See also this and n3337 (the C++11 standard).
But C++20 or later might add modules, and then things become different.
Practically speaking, for a small program (e.g. less than a few dozen thousands lines of your C++ code) a common approach is to have a single header file -which you would #include
in each of your 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 explanation)
Consider also using a good enough build automation toolset. On Linux, that might be a combination of GCC or Clang, ccache, with make or ninja, etc...
Upvotes: -1
Reputation: 17454
Yes, but only if they match.
You forward declared a global type string
, not in namespace std
.
You could probably make it work with namespace std {}
but then your program would have undefined behaviour, because you're not allowed to declare new things in that namespace (with a few exceptions).
In general, you want to avoid forward declarations for anything but your own classes.
Just #include <string>
. If doing so is causing problems, you should resolve those independently.
Upvotes: 3