Macros to disallow class copy and assignment. Google -vs- Qt

前端 未结 11 1242
伪装坚强ぢ
伪装坚强ぢ 2020-12-13 06:22

To disallow copying or assigning a class it\'s common practice to make the copy constructor and assignment operator private. Both Google and Qt have macros to make this eas

相关标签:
11条回答
  • 2020-12-13 06:54

    Others have already answered why it's legal to have different return values for operator=; IMHO jalf said it best.

    However, you might wonder why Google uses a different return type, and I suspect it's this:

    You don't have to repeat the type name when disabling the assignment operator like this. Usually the type name is the longest part of the declaration.

    Of course, this reason is void given that a macro is used but still - old habits die hard. :-)

    0 讨论(0)
  • 2020-12-13 06:55

    See Boost.Utility, specifically boost::noncopyable. It's not a macro but a base class with private copy and assignment. It prevents the compiler from generating implicit copy and assignment in derived classes.

    edit: Sorry, this was not an answer to the original question. By the way, boost::noncopyable uses a const reference as return type for the assignment operator. I was under the impression that the type of the return value doesn't matter since it's not supposed to be used. Still, making the operator private doesn't prevent usage inside the class or friends in which case a non-usual return type (like void, a const reference, etc) might lead to compilation errors and catch additional bugs.

    0 讨论(0)
  • 2020-12-13 06:56

    There's no practical difference. The assignment operator signatures differ just as a matter of style. It's usual to have an assignment operator returning a reference to allow chaining:

    a = b = c;

    but a version returning void is also legal and will work just fine for cases when the only purpose is to just declare the operator private and therefore prohibited to use.

    0 讨论(0)
  • 2020-12-13 06:59

    It doesn't matter. The return type is not part of a function's signature, as it does not participate in overload resolution. So when you attempt to perform an assignment, both declarations will match, regardless of whether you use the return type.

    And since the entire point in these macros is that the functions will never get called, it doesn't matter that one returns void.

    0 讨论(0)
  • 2020-12-13 07:02

    In practice I would say that both should not be used anymore if you have a C++11 compiler.

    You should instead use the delete feature , see here

    Meaning of = delete after function declaration

    and here

    http://www.stroustrup.com/C++11FAQ.html#default

    Why : essentially because compiler message is much more clearer. When the compiler need one of the copy or copy assignment operator, it immediately points out to the line where the =delete was coded.

    Better and complete explanations can also be found in Item 11: Prefer deleted functions to private undefined ones from Effective Modern C++ book by Scott Meyers

    0 讨论(0)
  • 2020-12-13 07:06

    As several other answers have mentioned, the return type of the function doesn't participate in the function signature, so both declarations are equivalent as far as making the assignment operator unusable by clients of the class.

    Personally I prefer the idiom of having a class privately inherit from an empty non-copyable base class (like boost::noncopyable, but I have my own so I can use it in projects that don't have boost available). The empty base class optimization takes care of making sure there's zero overhead, and it's simple, readable, and doesn't rely on the dreaded preprocessor macro functionality.

    It also has the advantage that copy and assignment can't even be used within class implementation code - it'll fail at compile time while these macros will fail at link time (likely with a less informative error message).

    0 讨论(0)
提交回复
热议问题