Most of the time, I "avoid" to have the following style in my single header file.
class a {
void fun();
};
void a::fun() {
}
In order to avoid the following error. I try to separate class definition in cpp file and class declaration in h file. For example, the below is the wrong example :
main.cpp
#include "b.h"
#include "a.h"
int main()
{
a aa;
b bb;
}
a.h
#ifndef A_H
#define A_H
#include <iostream>
class a {
public:
virtual int fun();
};
int a::fun()
{
int t;
std::cout << "a" << std::endl;
return t;
}
#endif
b.h
#ifndef B_H
#define B_H
#include <iostream>
#include "a.h"
class b {
public:
b();
};
#endif
b.cpp
#include "b.h"
#include "a.h"
b::b()
{
a aa;
aa.fun();
}
I will get the following error :
1>b.obj : error LNK2005: "public: virtual int __thiscall a::fun(void)" (?fun@a@@UAEHXZ) already defined in main.obj
However, when come to template, I will usually do it this way :
a.h
#ifndef A_H
#define A_H
#include <iostream>
template <typename T>
class a {
public:
virtual T fun();
};
template<typename 开发者_运维问答T> T a<T>::fun()
{
T t;
std::cout << "a" << std::endl;
return t;
}
#endif
May I know it this a good practice?
Thanks.
Cheok
You can eliminate the LNK2005 error by declaring the definition of a::fun()
as inline
. For example:
// a.h
// ...
inline int a::fun()
{
int t;
std::cout << "a" << std::endl;
return t;
}
With templates, the problem doesn't occur because the compiler/linker take care of ensuring that there is only one definition of each template instantiation.
If, for some reason, you don't want the function to be inline
, then you'll have to ensure that it only gets compiled once. For example, something like this:
// a.h
// ...
#ifdef DEFINE_CLASS_A_FUNCTIONS
int a::fun()
{
int t;
std::cout << "a" << std::endl;
return t;
}
#endif
and then, somewhere, you'll need to do something like this (exactly once):
#define DEFINE_CLASS_A_FUNCTIONS
#include "a.h"
1>b.obj : error LNK2005: "public: virtual int __thiscall a::fun(void)" (?fun@a@@UAEHXZ) already defined in main.obj
You are getting this error because a::fun()
is not inline
inline int a::fun()
{
int t;
std::cout << "a" << std::endl;
return t;
}
Also, refer C++ FAQ : How can I avoid linker errors with my template functions?
精彩评论