How to generate a compiler warning/error when object sliced

后端 未结 8 1591
执笔经年
执笔经年 2021-02-04 03:58

I want to know if it is possible to let compiler issue a warning/error for code as following:

Note:

1. Yea, it is bad programming style and

8条回答
  •  情深已故
    2021-02-04 04:09

    As a variation of Andrew Khosravian's answer, I'll suggest using templated copy constructors and assignment operators. This way you don't need to know all the derived classes of a given base class in order to safeguard that base class against slicing:

    class Base
    {
    private:   // To force a compile error for non-friends (thanks bk1e)
    // Not implemented, so will cause a link error for friends
        template Base(T const& d);
        template Base const& operator=(T const& rhs);
    
    public:
    // You now need to provide a copy ctor and assignment operator for Base
        Base(Base const& d) { /* Initialise *this from d */ }
        Base const& operator=(Base const& rhs) { /* Copy d to *this */ }
    };
    

    Although this reduces the amount of work needed, with this approach you still need to mess with each base class in order to safeguard it. Also, it will cause problems if there are legitimate conversions from Base to SomeOtherClass that employ an operator Base() member of SomeOtherClass. (In that case, a more elaborate solution involving boost::disable_if > can be used.) In any case, you should remove this code once you've identified all instances of object slicing.

    To the compiler implementors of the world: Testing for object slicing is definitely something that would be worthwhile creating (optional) warnings for! I can't think of one instance where it would be desired behaviour, and it's very commonly seen in newbie C++ code.

    [EDIT 27/3/2015:] As pointed out by Matt McNab, you actually don't need to declare the copy constructor and assignment operator explicitly as I've done above, as they will still be implicitly declared by the compiler. In the 2003 C++ standard, this is explicitly mentioned in footnote 106 under 12.8/2:

    Because a template constructor is never a copy constructor, the presence of such a template does not suppress the implicit declaration of a copy constructor. Template constructors participate in overload resolution with other constructors, including copy constructors, and a template constructor may be used to copy an object if it provides a better match than other constructors.

提交回复
热议问题