类与结构
使用 class 或 struct 关键字是一个品味问题,以及它给读者带来的“感觉”。从技术上讲,它们是等价的,但是如果将结构用于 POD 并将 C-struct 类型和类用于其他任何东西,则可读性会更好。
应该在 C++ 结构中包含的基本内容:初始化数据的构造函数(我不喜欢使用 memset,如果 POD 演变成不同的东西,它以后可能会反悔)或从其他类型构造但不是复制构造函数。
如果因为生成的编译器不够好而需要定义复制构造函数或赋值运算符,则将其设为类。
通常也将结构用于将传递给 STL 算法和模板元编程的函子,如
struct square_int {
int operator()( int value )
{
return value*value;
}
};
std::transform( v.begin(), v.end(), v.begin(), square_int() );
或者
// off the top of my head
template <typename T>
struct is_pointer { enum { value = false } };
template <typename T>
struct is_pointer<T*> { enum { value = true } };
成员方法与自由函数
除了我之前说过的,不要添加到其他人已经回答的内容之外,我想把重点放在你在帖子中评论的其他类型的函数上,比如比较运算符等。
对称的运算符(比较、算术)、插入和删除运算符以及转换通常最好作为自由函数实现,无论您将其声明为类还是结构。
对称运算符(关于数据类型)如果被实现为成员函数,则它们不是对称的。查找规则不会将左侧转换为调用成员函数,但它会应用相同的转换来匹配自由函数。
// Example of symmetry with free functions where method would be asymmetric
int main()
{
std::string( "Hello " ) + "world"; // compiles as free / member function
"Hello " + std::string( "world" ); // compiles with free function, fails with member function definition of +
}
在上面的代码中,如果 operator+ 是 std::string 的成员方法,则编译器将无法编译,因为它无法将 const char* 文字转换为 std::string 以使用该成员方法。
流的插入和提取必须始终作为自由函数实现,因为流始终位于操作的左侧。
将转换保持为自由函数将两种不同的类型解耦。如果 A 和 A' 可以相互转换,并且您决定将转换作为 A 的成员来实现,那么 A 必须知道 A' 并且 A 的所有使用都将取决于 A' 是否使用它。如果将转换定义为自由函数,则没有 A' 的 A 是完整的,并且两个类/结构之间的耦合会更小。与网络、序列化和反序列化的转换也是如此。当您在类/结构中实现它们时,您会强制所有用户了解这些转换。