【问题标题】:class definition and class declaration类定义和类声明
【发布时间】:2013-05-28 19:30:06
【问题描述】:

我正在阅读编程原理和使用 c++ 的实践(Bjarne Stroustrup),

9.4.4 定义成员函数,第 312 页,它说

1.

类定义中编写成员函数的定义有两个效果...

2.

不要将成员函数体放在类声明中,除非你知道...

作者写错了吗?讲的是同一件事,为什么第一句是“类定义”,第二句是“类声明”?

谢谢

【问题讨论】:

  • 作者谈到在类定义中定义成员函数有哪些缺陷?仅供参考,对于类模板,这样做是必要的。
  • 是的……除了行话怪癖之外,这听起来像是个坏建议。在class {} 块内定义函数没有错;这通常是实现inline 函数的最清晰方法。对于类模板的非模板友元的(不常见)情况,您必须在该范围内定义它。
  • @Praetorian - 在类定义中定义成员函数对于类模板不需要。这是一种常见的风格,使代码看起来很像 Java。但总的来说,没有什么可以阻止在模板定义之外使用适当的限定名称定义成员函数。
  • @PeteBecker 真;但我指的是将定义与源文件和头文件中的声明分开,在类模板的情况下你不能这样做(除非你也#include源文件)。

标签: c++ class


【解决方案1】:

作者写错了吗?

没有错,但不准确。一个类声明可以是前向声明,如:

class X;

这只是让编译器知道该类的存在,但没有指定该类有哪些成员、哪些基类等等(这就是类定义所做的)。

不过,声明也可以是定义,如:

class X
{
    // ...
};

所以从某种意义上说,既然定义也是一个声明,那么这句话并没有错。

这句话在常识假设下是错误的,即 declaration 我们的意思是 declaration 这不是定义,但在处理此类术语时,它可能是最好记住它们的正式定义。

【讨论】:

  • 但是类定义也可以是类声明,对吧?例如。 [class.name]/2 “仅由 class-key identifier; 组成的声明要么是在当前范围内重新声明名称,要么是将该标识符作为类名的前向声明。”因此,您可以将函数体放在类声明中——如果它包含 class-specifier / 类定义。?
  • 这是完全不正确的。您的示例是 forward 声明。一般来说,声明可以是前向声明或定义。引用的作者并非完全错误,只是不合理地不精确。
  • @DyP:是的,严格来说,你是对的。我的常识假设是,“声明”是指“不是定义的声明”,但实际上这不一定是正确的假设。我编辑了答案,谢谢
  • @Potatoswatter:你是对的。正如我在上面的评论中所写,我做了一个常识性的假设,这在处理正式术语时不太合适。我编辑了答案,谢谢
【解决方案2】:

类声明是你声明类的地方。或作为

来自 C++ 标准第 3.1 节:

声明将名称引入翻译单元或重新声明 先前声明引入的名称。声明指定 这些名称的解释和属性。

本质上,声明告诉编译器存在具有特定名称的特定对象、变量等。一个编译单元中可以有多个声明

在某种程度上是这样的

class X; // is declaration also known as forward declaration.

只是一个声明。 但是,每个对象/变量必须始终只有一个且只有一个定义。 定义基本上是编译器创建该类/对象/结构/变量等实例所需的一切。

在c++中,很多时候类声明也可以是定义或部分定义/

//declare a class and declare it's members.
class X { //declares X and starts to define it
   void test ();  //declare test method
   int b;         // declare b member
}

完整的定义可以在 .cpp 文件中,如下所示:

void X::test() {
  //test code
}

或在这样的类声明中:

   class X {
      void test () {
         //test code
      }

这里是关于差异的广泛讨论:

What is the difference between a definition and a declaration?

我相信作者建议您不要使用第二种类型的声明,您可以在类定义中声明和定义方法,而是在单独的 c++ 文件中。这是因为 C++ 只定义一次规则,您不希望从多个文件中包含同一个 .h 文件并且对同一个类有多个定义。

这里是另一个关于为什么要分开的广泛讨论:

Is is a good practice to put the definition of C++ classes into the header file?

【讨论】:

  • 我没有投反对票,但成员函数的定义不是类定义的一部分。函数体可能出现在类定义中,但这并不使其成为定义类所需的一部分。
  • 我同意,声明某事意味着您拥有创建它的所有信息..所以本质上您不需要声明创建类实例的方法..但是,很多时候将所有它们在同一个地方,而不是分成标题和cpp,你会遇到问题:)
  • 不,class X;X 的完美声明。声明 IMO 是引入具有所有必要信息的 name 以了解 name 所指的内容(它是变量、类型、函数吗?模板?等) A forward-declaration 类是纯声明(或重新声明),definition 类既是(重新)声明又是定义。一个类必须在从它创建实例之前定义(并因此声明)。
  • void X::test() { //test code } 不是一个实现而不是一个定义吗?
【解决方案3】:

从 OOP 语言的不同角度来看,接口意味着类的声明及其方法。在 C++ 中,您可以将其放在某个头文件中。类的实现就是这个类的方法的实现。例如,在 Java 中,您可以使用一个抽象类,其中一些方法已实现,而另一些则没有。但是抽象类或接口不能被实例化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-27
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    相关资源
    最近更新 更多