문제

I have a class like this:

class A {
    ...private functions, variables, etc...
public:
    ...some public functions and variables...

    A operator * (double);
    A operator / (double);
    A operator * (A);
    ...and lots of other operators
}

However, I want to also be able to do stuff like 2 * A instead of only being allowed to do A * 2, and so I would need functions like these outside of the class:

A operator * (double, A);
A operator / (double, A);
...etc...

Should I put all these operators outside of the class for consistency, or should I keep half inside and half outside?

도움이 되었습니까?

해결책

So what you are saying is that because you must put some operators (the ones that don't have A as the first param) outside the class, maybe you should put them all there so people know where to find them? I don't think so. I expect to find operators inside the class if at all possible. Certainly put the "outside" ones in the same file, that will help. And if the outside ones need access to private member variables, then adding the friend lines is a huge hint to look elsewhere in the file for those operators.

Would I go so far as to include the friend lines even if my implementation of the operators could actually be done with public getters and setters? I think I would. I think of those operators as really being part of the class. It's just that the language syntax requires them to be free functions. So generally I use friend and I write them as though they were member functions, not using getters and setters. It's a pleasant side effect that the resulting need for friend statements will cause them all to be listed in the definition of the class.

다른 팁

IMHO, the concern shouldn't be with stylistic consistency, but with encapsulation consistency; generally if a function does not need access to private members, it should not be part of the class. This is not a hard an fast rule, see arguments for it here.

So if your operators do not require private access, put them all outside. Otherwise, they will all have to be inside like so:

class A {
    ...
public:
    ...
    A operator * (double);
    A operator / (double);
    friend A operator * (double, A);
    friend A operator / (double, A);
    ...
};

From your replies to comments in the question it seems that you have an implicit conversion from double to A in your class. something like:

class A
{
    // ...
public:
    A(double);

    // ...
};

In this case you can simply define a free function for each operator of the form:

A operator*( const A&, const A& );

and it will be used if either side is an A object and the other side is implicitly convertible to an A. For this reason it is often preferable to make symmetric binary operators free functions.

Frequently it can be easier to implement binary * in terms of the assignment version *=. In this case I would make the assignment version a member function and define * as something like:

A operator*( const A& l, const A& r )
{
    A result(l);
    result += r;
    return result;
}

Otherwise as operator* is plainly part of your class interface I would have no problem with making it a friend if required.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top