我知道三种不同的实施方式"位置"对于我的班级方法:
1)在我的类(.h文件)中定义方法并在我的.cpp文件中实现它
//.h
class Foo
{
int getVal() const;
};
//.cpp
int Foo::getVal() const
{ return 0; }
2)在我的类(.h文件)中定义并实现该方法。
//.h
class Foo
{
int getVal() const
{ return 0; }
};
3)在我的类中定义方法,并在类外但在我的头文件中实现它。
//.h
class Foo
{
int getVal() const;
};
int Foo::getVal() const
{ return 0; }
这三种方法有哪些主要区别?
答案 0 :(得分:9)
这个问题有三个要素:可读性(代码看起来有多好),编译(编译器可以优化多少)和实现隐藏(如果将代码用作库,则可能不希望显式共享你和世界的特别酱油。
方法一只公开头文件中函数的接口。这意味着您将显示一个漂亮的干净界面,并且您的实现不会以纯文本形式公开。但是,代码不能跨编译单元内联,因此它有可能在运行时稍慢(实际上,这仅对非常非常非常小的代码百分比很重要)。这应该是你的默认方式。
方法2是隐式内联。冗长的功能会让你的课程变得混乱,因为(imho)很糟糕。同时将您的实现暴露给全世界。但是,该函数可以内联,并且比在另一个地方定义它更简洁。我保留这个非常小的功能。
方法3实际上是非法的,因为您将破坏单定义规则,但以下情况很好:
//Foo.h
class Foo {
int getVal() const;
};
inline int Foo::getVal() const {
return 0;
}
当我想保持类定义干净但想要头文件中的函数定义(对于inlinable或模板函数)时,我使用它。
答案 1 :(得分:2)
(1)将为一个大项目编译得更快(只需要在Foo.cpp中编译getVal
一次的定义,并且只需要在定义更改时重新编译一件事),并且你得到一个非常明确的一个类的接口,供想要查找的人使用。另一方面,您无法内联getVal()
。
(2)和(3)将编译得更慢,并为您的定义更改添加更多依赖项。但是你可以内联getVal()
。如果getVal
是模板函数,则还需要这样做。如果您的标题被多次包含,注意(3)将导致链接器错误 - 您必须标记记住标记您的函数inline
。这是偏好(1)和(2)到(3)的一个很好的理由。
真的不是挑选(1)vs(2)。您可能会在大型项目中使用它们 - 在头文件中放置应该内联的函数的定义(和模板),并在cpp中放置内联不太合理的内容。
答案 2 :(得分:1)
在我开始之前的一个小注释,有很多用于描述这些内容的非常类似的单词,我将使用头文件中的部分声明(int getVal() const
)和部分的实现cpp文件(int Foo::getVal() const
)。如果这些不完全准确,请道歉。
另请注意,如果不明确,则其他人将受到处罚。
1)在我的类(.h文件)中定义方法并在我的.cpp文件中实现它
这被认为是标准方法,并且通常被认为是默认方法(有很多例外,因此默认可能有点强)。
它将声明与实现分开。这提供了一些好处:
2)在我的类(.h文件)中定义并实现该方法。
这称为内联实现,只应在简单实现中使用。它也有一些好处:
3)在我的类中定义方法,并在类外但在我的头文件中实现它。
我之前没有看过这个,但是假设它在定义非平凡时使用,但你希望内联的好处是2. IdeaHat提到inline
关键字是必需的这种情况。