English 中文(简体)
Consistency in placing operator functions
原标题:

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.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签