在头定义库的类定义中实现的任何区别?

non*_*one 6 c++ header-files

我正在开发一个大量使用模板的库,因此我决定将其作为一个仅限标题的库.由于声明和实现在同一个文件中,我现在可以同时执行这两个操作.所以我可以选择这两种风格:

// 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
    }
};
Run Code Online (Sandbox Code Playgroud)

我想知道这两个编译器之间是否存在差异.如果不是你会推荐哪一个更好的做法?

Dra*_*rax 2

如果合并定义和实现,您将在解决交叉/循环依赖关系时遇到问题。



例如:

1. 使用第二个选项

主页.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
Run Code Online (Sandbox Code Playgroud)

人类.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
Run Code Online (Sandbox Code Playgroud)

您不能使用其他对象。



而如果您将实现拆分到另一个文件中:

2. 使用你的第一个选择

主页.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
Run Code Online (Sandbox Code Playgroud)

主页.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
Run Code Online (Sandbox Code Playgroud)

人类.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
Run Code Online (Sandbox Code Playgroud)

人类.ip

#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
Run Code Online (Sandbox Code Playgroud)

事情进行得更加顺利



3. 其他考虑因素

  • 有人还可能会争辩说,您应该将代码放在多个文件中,这与您不将整个项目编码在单个文件中的原因相同,只是为了拆分内容以使它们更容易理解。
  • 作为最后一个奖励点,为了与 .hpp/.cpp 文件对称,这将使每个开发人员内心深处(对某些人来说非常深)的完美主义者安静下来:)