C++二元运算符重载的两种实现:差异、优劣及编程规范探讨
Hey there! Since you're new to C++, I’ll break this down in plain terms so it’s easy to follow. Let’s start with the core differences between these two operator+ overloads, then cover their pros/cons and common best practices.
Core Differences
The key split comes down to how the operands are handled:
- Member Function Version: When you write
d1 + d2, this is just shorthand ford1.operator+(d2). The left operand (d1) becomes the*thisobject inside the function, and the right operand (d2) is passed as a parameter. The operator is a direct part of theDistanceclass. - Friend Function Version: This is a standalone function that’s granted access to the class’s private members. Calling
d1 + d2translates tooperator+(d1, d2)—both operands are explicit parameters, with no implicit*thisobject.
Pros and Cons of Each Approach
Member Function operator+
Pros:
- Clear class association: Anyone reading the code can immediately see this operator is part of the
Distanceclass’s interface. - Enforces left operand type: You can’t accidentally use a non-
Distancevalue as the left operand (like5 + d1) unless you add a conversion constructor. This prevents some unexpected behavior.
Cons:
- No symmetry for mixed types: You can’t directly support operations where the left operand isn’t a
Distance(e.g.,int + Distance). To make that work, you’d need a separate non-member overload. - Inefficient in your example: You’re passing the right operand by value, which creates a copy of
d2. For larger classes, this wastes memory and time—you should useconst Distance& d2instead.
Friend Function operator+
Pros:
- Symmetric operations: If your
Distanceclass has a constructor that convertsinttoDistance(like yourDistance(int v)), this version automatically supports bothd1 + d2and5 + d1. Both operands are treated equally. - More efficient: Your example passes both operands by
const reference, which avoids unnecessary copies—perfect for bigger objects.
Cons:
- Minor encapsulation break: Since it’s a friend, it can access private members directly. This is a controlled exception, but some programmers prefer to avoid friends unless strictly necessary.
- Less obvious class tie-in: At first glance, someone might not realize this function is linked to the
Distanceclass unless they check the class declaration.
Common Programming Conventions
Here’s what most C++ developers follow for operator overloading:
- Use member functions for modifying operators: Operators like
operator+=,operator++, oroperator=that change the left operand should be members—this makes it clear you’re modifying*this. - Use non-member functions for symmetric operators: For
operator+,operator-,operator==, oroperator<<(forcout), non-member functions (friend or not) are preferred because they support symmetric conversions. - Pass operands by
const reference: Always do this for binary operators that don’t modify operands (likeoperator+). It’s faster and avoids copying. - Return by value for new objects: Both your examples do this right—
operator+creates a newDistanceobject, so returning by value is correct. - Avoid friends when possible: If you can implement the non-member operator using public class methods, skip the friend declaration. For example, you could build
operator+usingoperator+=(a member function):
This keeps encapsulation intact without needing a friend.Distance operator+(const Distance& left, const Distance& right) { Distance temp = left; temp += right; // Reuse the member operator+= return temp; }
内容的提问来源于stack exchange,提问作者Ayto Maximo
相关产品推荐
相关产品推荐

