Deleting copy constructor breaks inherited constructors

寵の児 提交于 2019-12-04 00:26:44

The problem is that marking a copy constructor with delete makes it user-declared, which in effect deletes the default constructor of that class (in your case Derived). The behaviour can be seen in this simple code:

struct X
{
    X(const X&) = delete; // now the default constructor is not defined anymore
};

int main() 
{
    X x; // cannot construct X, default constructor is inaccessible 
}

As a side remark: even if Base::Base() would be inherited, the compiler would see it like Derived(): Base(){}. But Derived is deleted, so it cannot really call Base::Base(). In general, a using Base::Base statement is just syntactic sugar for the corresponding compiler-generated Derived(params): Base(params){}.

Whenever you define a custom constructor you need to provide a default constructor explicitly. I.e.

Derived::Derived() = default;

Inheriting constructors doesn't get the special constructors -- empty, copy, move. This is because what you are asking for literally is almost always a bad idea.


Examine:

struct base {
  std::vector<int> data;
  base(base const&)=default;
  base(base&&)=default;
  base(size_t n):data(n) {}
  base()=default;
};

struct derived:base {
  using base::base;
  std::vector<char> more_data;
};

do you really want derived(base const&) to exist? Or base(base&&)? Both would hopelessly slice derived.

The danger of those operations happening "accidentally" means you have to bring them in explicitly if you want them.


The copy/move/default ctors, by default, happen to just call the parent version, plus the ctors of member variables. There is no need (usually) to involve inheriting them from your parent.

However, once you =delete, =default or define one of these special ctors, the other ones stop being generated by the compiler. So you have to =default the other ones, if you still want them to stick around.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!