13

假设我有 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 之间的区别?

4

3 回答 3

29

TR;博士

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

解释

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

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

于 2013-10-02T21:38:27.170 回答
9

我在使用 .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();
}
于 2018-10-10T10:38:34.197 回答
0

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

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

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

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

于 2021-08-17T14:51:18.353 回答