【问题标题】:Difference between using .ipp extension and .cpp extension files使用 .ipp 扩展名和 .cpp 扩展名文件的区别
【发布时间】:2013-10-09 10:39:29
【问题描述】:

假设我有 2 个头文件、1 个 .ipp 扩展文件和一个 main.cpp 文件:

第一个头文件(类似于Java中的接口):

template<class T>

class myClass1{

public:


    virtual int size() = 0;

};

第二个头文件:

#include "myClass1.h"



    template<class T>

    class myClass2 : public myClass1<T>

     public:



    {

          virtual int size();


     private:

         int numItems;

    };

    #include "myClass2.ipp"

然后是我的 myClass2.ipp 文件:

template <class T>
int myClass2<T>::size()
{

  return numItems;
}

最后一个是我的主要:

#include "myclass2.h"
void tester()
{
  myClass2<int> ForTesting;
  if(ForTesting.size() == 0)
  {
    //......
  } 
  else 
  {
   //.....
  }
}

int main(){

   tester();
   return 0;

}

myClass1、myClass2 和 myClass2.ipp 属于头文件。源文件中的 main.cpp。 使用这种方式来实现你的程序而不是仅仅使用有什么好处 .h 和 .cpp 文件?什么是.ipp 扩展文件? .ipp 和 .cpp 的区别?

【问题讨论】:

标签: c++


【解决方案1】:

TR;DR

.cpp 文件是一个单独的翻译单元,.ipp 包含在标头中,并进入包括该标头在内的所有翻译单元。

说明

在模板之前,您将方法的声明放在头文件中,并且实现转到.cpp 文件。这些文件被单独编译为它们自己的编译单元。

使用模板,这不再可能几乎所有模板方法都需要在标题中定义。为了至少在逻辑层面上将它们分开,有些人将声明放在标题中,但将模板方法的所有实现移动到 .ipp 文件(i 表示“内联”)并在末尾包含 .ipp 文件标题。

【讨论】:

  • 一些站点使用后缀“.hpp”而不是“.h”作为C++头文件;有些使用“.h++”,有些使用“.H”,有些使用“.hxx”。 YMMV。我工作的一个地方对打算用英特尔 C++ 编译器编译的文件使用“.ipp”后缀。虽然编译器可能会使用扩展名来区分 C 与 C++ 编译单元,但大多数情况下编译器并不在意它们。
  • 1.将方法的声明放在头文件中,实现转到.cpp文件。 2.将声明放在标题中,但将模板方法的所有实现移动到 .ipp 文件(i 表示“内联”)并在标题末尾包含 .ipp 文件。为什么有些人选择第二个?好点了吗?
  • @14K 模板不可能将定义放入单独的编译单元,因为编译器需要在模板被实例化的任何地方查看定义。因此,您只有两个选择:将 everything 放入标头 将声明放入标头,将模板定义放入单独的文件中,该文件包含在标头的末尾.
  • 请记住,类模板不是类,模板成员函数也不是函数。它们是用于创建类和函数的模式,因此无论在何处使用它们都必须完全可见。
  • @DanielFrey 除非您知道所需的全部特化,因此可以使用显式实例化。
【解决方案2】:

我看到使用 .ipp 文件的另一个优点是您可以选择是否包含模板的实现部分。这允许您通过为 .cpp 文件中的某些参数实例化模板来减少编译时间,这样它们就可以进行预编译,同时保留为其他参数实例化模板的可能性。示例:

// x.hpp
template <typename T>
struct X
{
    int f();
}

// x.ipp
#include "x.hpp"

template <typename T>
int X::f()
{
    return 42;
}

// x.cpp
#include "x.ipp"

// Explicit instantiation of X<> for int and double;
// the code for X<int> and X<double> will be generated here.
template class X<int>;
template class x<double>;

// foo.cpp
// Compilation time is reduced because 
// the definitions of X member functions are not parsed.
#include "x.hpp"

void foo()
{
    X<int> x;
    x.f();
}


// bar.cpp
// Here we need to include the .ipp file because we need to instantiate
// X<> for a type which is not explicitly instantiated in x.cpp.
#include "x.ipp"
#include <string>

void bar()
{
    X<std::string> x;
    x.f();
}

【讨论】:

    【解决方案3】:

    据我了解,C++ 中的文件扩展名(.h、.cpp 等)是约定俗成的。你可以随心所欲地调用它们,编译器会做它的事情。您会注意到标准模板库包含文件没有扩展名。

    #include 将拉入它给定的任何文件。还是会? Wikipedia 特别提到了“文本文件”,因此尝试在该行包含类似 .jpg 的内容可能会失败(而不是在编译器尝试解析您刚刚交给它的任何垃圾时)。

    另一方面,支持工具?我猜如果你在线条之外着色太远,有些工具会令人窒息。我没有遇到它,但我没有尝试将我的 .cpp 文件扩展名更改为 .seapeapee 或其他东西。海豌豆尿显然是指一种水生植物(我刚刚编造的),它偶尔会释放出高尿酸的液体。很明显。

    Java 等其他语言要严格得多,需要特定的扩展名,例如 .java 才能正确编译。

    【讨论】:

      猜你喜欢
      • 2013-12-19
      • 2010-12-05
      • 1970-01-01
      • 2011-10-10
      • 2015-04-02
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      相关资源
      最近更新 更多