这两种定义方法之间有区别吗?

时间:2012-10-17 14:56:37

标签: c++ coding-style member

选项1:

//A.h
class A
{
   void foo()
   {
   }
};

选项2:

//A.h
class A
{
    void foo();
};

inline void A::foo()
{
}

请注意,在选项2中,该方法也在标题中实现(标记为inline以防止多重定义)。

5 个答案:

答案 0 :(得分:4)

正如你所呈现的那样,没有任何区别。但是,第二种形式有时用于利用可能跟随class A的声明。

例如:

class A
{
  void foo();
};
class B : A { };
inline void A::foo() {
   B b;
}

在第一种形式中,使用B是不可能的。

答案 1 :(得分:1)

在类定义中定义的方法是隐式inline,因此,在功能上,没有区别。

Rob提供了一个区别的好理由。这是另一个,IMO。

说你有:

class DBConnection
{
public:
   DBConnection(const Config& config)
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   void reconnect()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   void checkIntegrity()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   void runQuery()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   void dropTables()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   void disconnected(Callback callback)
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   void selectTables()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   Results getResults()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
        //YES, I copy-pasted these
   }
   //MANY MORE
}

告诉我,有没有办法在数据库断开连接时得到通知?

现在,请再试一次:

class DBConnection
{
public:
   DBConnection(const Config& config);
   void reconnect();
   void checkIntegrity();
   void runQuery();
   void dropTables();
   void disconnected(Callback callback);
   void selectTables();
   Results getResults();
   //MANY MORE
};

inline DBConnection::DBConnection(const Config& config)
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   inline void DBConnection::reconnect()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   inline void DBConnection::checkIntegrity()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   inline void DBConnection::runQuery()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   inline void DBConnection::dropTables()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   inline void DBConnection::disconnected(Callback callback)
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   inline void DBConnection::selectTables()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
   }
   inline Results DBConnection::getResults()
   {
        //some
        //really
        //complicated
        //logic
        //and
        //checks
        //and
        //stuff
        //I dunno
        //not
        //a
        //db
        //guy
        //possibly
        //exceptions
        //thrown?
        //YES, I copy-pasted these
   }

更容易,对吧?

答案 2 :(得分:0)

第二个更适用于长函数(可读性)和函数,其实现取决于其他类的前向声明:

<强> B.h

class A;
class B {
public:
  void foo(A*);
};
#include "B_impl.h"

<强> B_impl.h

#include <B.h>
#include <A.h>

inline void B::foo(A* ptr)
{
   ptr->bar();
}

<强> A.H

class B;
class A {
public:
  void foo(B*);
};
#include "A_impl.h"

<强> A_impl.h

#include <A.h>
#include <B.h>

inline void A::foo(B* ptr)
{
   ptr->bar();
}

在第一种情况下,这种混合前瞻性声明的用法是不可能的。

此外,您可以拆分内联实现和类定义 - 可读性将显着增长......

答案 3 :(得分:0)

这两个定义之间并不存在重大差异。

在option1中,该方法被称为内联函数,即不允许循环和更多代码行。因为快速执行。

在option2中,称为外部正文定义,我们可以编写任何no.of行。

我认为内联意味着不会阻止多重定义。它意味着只需要少量代码而不需要循环等等。

答案 4 :(得分:0)

不,没有重大区别。两者都暗示编译器可能/应该内联方法foo()。

KerrekSB正确地指出它需要更多代码,但当然有一个好处:它提供了一个选项,即使使用内联方法,也可以将“接口”与“实现”分开。

例如,您可以在头文件的顶部显示类接口,并清楚地将.h文件的其余部分标记为“内联实现。或者,您可以在内联实现中包含第二个头文件。” p>

//A.h
class A
{
    void foo();
};
// "import" the inline implementations
#include "A.ipp"

然后让A.ipp如下:

//A.ipp
inline void A::foo()
{
}

一个小小的警告:由于“第三个非惯用的C ++文件类型”,它可能会导致与同事混淆:.h表示类,.cpp表示“普通”源文件,。py表示内联实现