你如何声明一个内联类?

时间:2012-03-03 19:01:38

标签: c++

我的家庭作业告诉我要内联声明一个类,但我只听说过内联声明函数。内联类声明的作用是什么,以及如何实现它?

2 个答案:

答案 0 :(得分:5)

我认为他们只是说你的类应该放在标题中,为方便起见,所有类方法都应该在类本身内联声明,而不是将类方法放在行外或单独的CPP中

这有点含糊不清,但这就是我对它的解释。

答案 1 :(得分:2)

比较函数和类:

一个函数可以有一个声明和一个定义:

ReturnType FunctionName(Parameter1, Parameter2); // a function declaration

ReturnType FunctionName(Parameter1, Parameter2) // a function definition
{
    // do something
    return ReturnType;
}

函数声明提供了任何想要调用函数的人所需的所有信息。

函数定义允许编译器生成机器代码,以便当有人调用函数时,将在可执行文件的某处调用将被调用的指令。

此生成的代码仅在可执行文件中存在一次。通常你会把函数定义放在一个.cpp文件中(或.c,如果你使用C,这也适用于它),它被编译并链接到可执行文件中。如果该.cpp文件未链接,您将收到链接器错误,指出FunctionName not found或类似的内容。

如果将函数定义放在头文件中,那么标题很可能会在系统的多个位置使用,并包含在其他.cpp文件中。这会在链接时FunctionName already defined in this, that, or the other object file产生相反的问题。

因此,函数通常不在头文件中定义,因为头文件通常包含在多个.cpp文件中,因此最终会产生重复的目标代码。

但是课程略有不同。您有两种不同的方法来为类定义函数。一种方法类似于上面定义的函数:

//myleanklass.h
class MyLeanKlass
{
public:
    void perform();
};

//myleanklass.cpp
void MyLeanKlass::perform()
{
    // Sing, dance, and play the piano
}

就像使用自由函数一样,我们可以将定义放在头文件中,只要它不包含在多个.cpp文件中即可。否则我们会再次遇到类似的链接器错误void MyLeanKlass::perform already defined ...这种情况不是常态。您通常会声明类,以便可以通过系统重用它们。因此标题将包含在多个位置并导致链接器错误。

为了清楚起见,我们可以将定义放在头文件中,但不是inline。您将无法在系统中多次包含此标题:

class MyLeanKlass
{
public:
    void perform();
};

void MyLeanKlass::perform()
{
    // Sing, dance, and play the piano
}

最后,我们得到了问题的答案。您可以在头文件中定义类函数,只要它们在类声明中即可。这称为inline definition。即使标头包含在多个.cpp文件中,它也不会导致编译单元中的多个定义,也不会导致链接器错误。

//myleanklass.h
class MyLeanKlass
{
public:
    void perform()
    {
        // Sing, dance, and play the piano
    }
};

然而,这种方法存在问题:

  • 内联类函数可能会使编译花费更长时间,因为编译器仍然会编译每个重复的类函数定义,并且只在链接时丢弃重复项。
  • 对类函数进行更改会导致重新编译包含它的任何.cpp文件,从而导致更长的重新编译时间。
  • 有时它是不可能的。如果一个类使用另一个类并且使用另一个类,那么您将具有循环依赖性,并且无法定义内联的所有内容。您可以通过将问题函数放入单独的.cpp文件来解决这个问题。