I read Scott Meyers' article on the subject and quite confused about what he is talking about. I have 3 questions here.
Question 1
To explain in detail, assume I am writing a simple vector<T>
class with methods like push_back
, insert
and operator []
. If I followed Meyers' algorithm, I would end up with all non-member friend functions. I will have a vector class with few private members and many non-member friend functions. Is this what he is talking about?
Question 2
I am still not understanding how non-member functions improve encapsulation. Consider the code given in Meyers' article.
class Point {
public:
int getXValue() const;
int getYValue() const;
void setXValue(int newXValue);
void setYValue(int newYValue);
private:
... // whatever...
};
If his algorithm is followed, setXXXX
methods should be non-members. My question is how that increases encapsulation? He also says
We've now seen that a reasonable way to gauge the amount of encapsulation in a class is to count the number of functions that might be broken if the class's implementation changes.
Until we keep the method signature intact when class implementation changes, no client code is gonna break and it is well encapsulated, right? The same applies for non-member functions as well. So what is the advantage non-member function provides?
Question 3
Quoting his algorithm
else if (f needs type conversions
on its left-most argument)
{
make f a non-member function;
if (f needs access to non-public
members of C)
make f a friend of C;
}
What he meant by f needs type conversions on its left-most argument? He also says the following in the article.
Furthermore, we now see that the common claim that "friend functions violate encapsulation" is not quite true. Friends don't violate encapsulation, they just decrease it — in exactly the same manner as a member functions.
This and the above algorithm are contradictory, right?
Question 1
In this case, following Meyers's algorithm will give you member functions:
operator<<
or operator>>
? No.His advice is to only make them friends when they really need to be; to favour non-member non-friends over members over friends.
Question 2
The SetXXXX
functions need to access the internal (private) representation of the class, so they can't be non-member non-friends; so, Meyers argues, they should be members rather than friends.
The encapsulation comes about by hiding the details of how the class is implemented; you define a public interface separately from a private implementation. If you then invent a better implementation, you can change it without changing the public interface, and any code using the class will continue to work. So Meyers's "number of functions which might be broken" counts the member and friend functions (which we can easily track down by looking at the class definition), but not any non-member non-friend functions using the class through its public interface.
Question 3
This has been answered.
The important points to take away from Meyers's advice are:
The meaning f needs type conversions on it left-most arg is as follows:
consider following senario :
Class Integer
{
private:
int num;
public:
int getNum( return num;)
Integer(int n = 0) { num = n;}
Integer(const Integer &rhs)) { num = rhs.num ;}
Integer operator * (const Integer &rhs)
{
return Integer(num * rhs.num);
}
}
int main()
{
Integer i1(5);
Integer i3 = i1 * 3; // valid
Integer i3 = 3 * i1 ; // error
}
In above code i3 = i1 * 3
is equivalent to this->operator*(3)
which is valid since 3 is implicitly converted to Integer.
Where as in later i3 = 3 * i1
is equivalent to 3.operator*(i1)
, as per rule when u overload operator using member function the invoking object must be of the same class.
but here its not that.
To make Integer i3 = 3 * i1
work one can define non-member function as follow :
Integer operator * (const Integer &lhs , const Integer &rhs) // non-member function
{
return Integer(lhs.getNum() * rhs.getNum());
}
I think you will get idea from this example.....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With