定义vs声明类

时间:2014-01-11 07:32:45

标签: c++ class declaration definition

请告诉我,我是否正确。

当我被要求声明一个班级时:

class Foo{
    int foo, bar;
public:
    Foo();
    Foo(int arg1, int arg2);
    void doSomething();
    int returnSomething();
    ~Foo();
};

但是当我被要求定义一个班级时:

class Foo{
    int foo, bar;
public:
    Foo(){};
    Foo(int arg1, int arg2):foo(arg1),bar(arg2){
        //body
    }
    void doSomething(){
       //body
    }
    int returnSomething(){
        return 0;
    };
    ~Foo(){
     // e.g. free the memory
     }
};

顺便说一句。我应该在声明或定义中或两者中放置初始化列表吗?

3 个答案:

答案 0 :(得分:3)

术语有些混乱。 声明可以是定义因此,您的示例都是class Foo声明定义。类定义是否定义了类的成员是另一回事。您的第一个示例仅声明成员函数并定义数据成员,而第二个示例定义所有成员。

这是一个类定义的类声明:

class Foo;

这些都在 3.1声明和定义[basic.def] 中列出。从该条款中得出最相关的例子:

struct X         // defines X
{
  int x;         // defines non-static data member x
  static int y;  // declares static data member y
  X() : x(0) {}  // defines a constructor of X
};

所以你可以看到上面的内容算作一个类定义。

  

我应该在声明或定义中或两者中放置初始化列表吗?

同样,这在术语上也存在同样的困惑。需要注意的重要一点是初始化列表只能在构造函数的定义中。因此,一旦将一个添加到构造函数声明中,此声明也将成为一个定义,并且您需要向其添加一个主体。

答案 1 :(得分:1)

  

请告诉我,我是否正确。

第一个是类的声明定义,第二个是类的声明,成员函数和成员对象以及其成员函数的定义

要仅定义成员函数,可以使用:

<return type> <class_name>::<function_name>(...) {...}

语法。


  

我应该在声明或定义中或两者中放置初始化列表吗?

构造函数的初始化列表应该只放在函数的定义中。

答案 2 :(得分:0)

编辑: @juanchopanza告诉我,我对术语声明和定义感到困惑,所以我输入了一个不完全正确的解释。我在这里纠正它,所以我不会忘记声明和定义之间的区别。

您的第一个样本是声明,第二个是声明和定义。

您的两个示例都定义了Foo。不同之处在于,在第一个文件中,您只是声明成员函数,但在第二个文件中,您实际上是在定义它们。

声明Foo的实际方法是class Foo;。要定义Foo使用class Foo { ... };

请注意,定义可以替换声明,即在您定义X时,您也会声明它。

以下是在实践中通常在头文件和源文件对中拆分声明和定义的方法。

foo.hpp (定义{{​​1}},但只声明其功能)

Foo

foo.cpp (成员函数定义)

#ifndef __FOO__
#define __FOO__

class Foo
{
        int foo, bar;
    public:
        Foo();
        Foo(int arg1, int arg2);
        void doSomething();
        int returnSomething();
        ~Foo();
};

#endif

您定义每个特定函数的位置(#include "foo.h" Foo::Foo() { } Foo::Foo(int arg1, int arg2) : foo(arg1), bar(arg2) { //body } Foo::~Foo() { // e.g. free the memory } void Foo::doSomething() { //body } int Foo::returnSomething() { return 0; }; foo.hpp)无关紧要,只要您只定义一次函数即可。可以在foo.cppfoo.hpp中定义,但不能同时在中定义。

关于初始化列表的问题

考虑一下:如果你在构造函数的声明上放置一个初始化列表,它就变成了声明定义。

例如,而不是定义

foo.cpp

在源文件中,我可以在标题中定义它:

Foo::Foo(int arg1, int arg2) :
    foo(arg1),
    bar(arg2)
{
    //body
}

唯一的区别是我没有使用范围运算符class Foo { ... Foo(int arg1, int arg2) : foo(arg1), bar(arg2) { //body } ... }; 。您不会将::放在您在类定义中声明或定义的函数前面,因为编译器已将它们识别为作用于该类的范围。