选项1:
//A.h
class A
{
void foo()
{
}
};
选项 2:
//A.h
class A
{
void foo();
};
inline void A::foo()
{
}
注意,在选项2中,该方法也在header中实现(标记inline
为防止多重定义)。
//A.h
class A
{
void foo()
{
}
};
//A.h
class A
{
void foo();
};
inline void A::foo()
{
}
注意,在选项2中,该方法也在header中实现(标记inline
为防止多重定义)。
正如您所介绍的那样,没有没有区别。但是,有时使用第二种形式来利用可能遵循的声明class A
。
例如:
class A
{
void foo();
};
class B : A { };
inline void A::foo() {
B b;
}
在第一种形式中,这样的使用B
是不可能的。
在类定义中定义的方法是隐式的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
}
更容易,对吧?
这两个定义之间没有主要区别。
在选项 1 中,该方法被称为内联函数,即不允许循环和更多代码行。因为执行速度快。
在选项2中,即称为外部体定义,我们可以编写任何行数。
我认为内联意味着不阻止多重定义。这意味着只做少量没有循环等的代码。
不,没有大的区别。两者都向编译器暗示方法 foo() 可能/应该被内联。
KerrekSB 正确地指出它需要更多代码,但当然有一个好处:它提供了一个选项,即使使用内联方法也可以将“接口”与“实现”分开。
例如,您可以在头文件的顶部显示类接口,并清楚地将 .h 文件的其余部分标记为“内联实现”。或者,您可以包含第二个带有内联实现的头文件。
//A.h
class A
{
void foo();
};
// "import" the inline implementations
#include "A.ipp"
然后有 A.ipp 如下:
//A.ipp
inline void A::foo()
{
}
一个小注意事项:由于“第三种非惯用的 C++ 文件类型”,它可能会引起您的同事的一些困惑:.h 用于类,.cpp 用于“普通”源文件,.ipp 用于内联实现。