我正在开发一个大量使用模板的库,因此我决定将其设为仅包含 header 的库。由于声明和实现在同一个文件中,我现在可以同时进行。所以我可以在这两种风格之间做出选择:
// seperate declaration and implementation
template <typename T>
class Klass {
public:
void do_something();
};
template <typename T>
void Klass<T>::do_something()
{
// do something
}
// or both at the same time
template <typename T>
class Klass {
public:
void do_something()
{
// do something
}
};
我想知道这两者对于编译器是否有区别。如果不是,您会推荐哪一个作为更好的做法?
最佳答案
如果合并定义和实现,您将无法解决交叉/循环依赖问题。
例如:
1。使用你的第二个选项
home.hpp
#ifndef HOME_HPP
# define HOME_HPP
# include <string>
# include "human.hpp"
template <typename T>
class Home
{
public:
Home()
:
color_("white"),
inhabitant_(this)
{
}
void set_color(const std::string& color)
{
color_ = color;
}
private:
std::string color_;
Human<T> inhabitant_;
};
#endif
human.hpp
#ifndef HUMAN_HPP
# define HUMAN_HPP
# include <string>
// Cannot include the other header here because it already includes us
//# include "house.hpp"
// So we do a forward declaration:
template<typename T>
class Home;
template <typename T>
class Human
{
public:
Human(Home<T>* house)
:
house_(house)
{
}
void paint(const std::string& color)
{
// Oops, we can't use House in our implementation
// because it is only forward declared
//house_->set_color(color);
}
private:
Home<T>* house_;
};
#endif
您不能使用其他对象。
而如果您将实现拆分到另一个文件中:
2。使用您的第一个选项
home.hpp
#ifndef HOME_HPP
# define HOME_HPP
# include <string>
# include "human.hpp"
template <typename T>
class Home
{
public:
Home();
void set_color(const std::string& color);
private:
std::string color_;
Human<T> inhabitant_;
};
#endif
home.ipp
#ifndef HOME_IPP
# define HOME_IPP
# include "home.hpp"
template<typename T>
Home<T>::Home()
:
color_("white"),
inhabitant_(this)
{
}
template<typename T>
void Home<T>::set_color(const std::string& color);
{
color_ = color;
}
#endif
human.hpp
#ifndef HUMAN_HPP
# define HUMAN_HPP
# include <string>
template<typename T>
class Home;
template <typename T>
class Human
{
public:
Human(Home<T>* house);
void paint(const std::string& color);
private:
Home<T>* house_;
};
#endif
human.ipp
#ifndef HUMAN_IPP
# define HUMAN_IPP
# include "human.hpp"
# include "house.ipp"
template<typename T>
Human<T>::Human(Home<T>* house)
:
house_(house)
{
}
template<typename T>
void Human<T>::paint(const std::string& color)
{
house_->set_color(color);
}
#endif
事情更顺利
3。其他注意事项
- 也有人会争辩说,您应该将代码放在多个文件中,原因与您不将整个项目编码在一个文件中的原因相同,只是为了拆分内容,使它们更易于理解。
- 作为最后的奖励点,为了与 .hpp/.cpp 文件对称,这将让每个开发人员内心深处(对某些人来说睡得很深)的完美主义者保持沉默 :)
关于c++ - 在仅 header 库的类定义中实现有什么不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25890133/