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.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.