Suppose I have a silly class hierarchy.
class Base {
public:
Base() = default;
virtual ~Base() = default;
virtual void print() = 0;
};
class Derived : public Base {
public:
Derived() {
stuff.resize(1000);
}
void print() override {
cout << "Whatever\n";
}
private:
std::vector<int> stuff;
};
And I want to use it like this:
void printIt(Base* b) {
b->print();
}
int main() {
Derived d1;
Derived d2 = d1;
printIt(&d1);
printIt(&d2);
}
This compiles and works fine, but Clang warns me:
warning: definition of implicit copy constructor for 'Base' is deprecated because it has a user-declared destructor
That seems fine and correct - if people copy Base
bad things will happen so I'll delete the copy constructor.
class Base {
public:
Base() = default;
virtual ~Base() = default;
virtual void print() = 0;
Base(const Base&) = delete;
Base& operator=(const Base&) = delete;
};
However then I get this error:
main.cpp:38:17: error: call to implicitly-deleted copy constructor of 'Derived'
Derived d2 = d1;
^ ~~
main.cpp:18:21: note: copy constructor of 'Derived' is implicitly deleted because base class 'Base' has a deleted copy
constructor
class Derived : public Base {
^
main.cpp:14:9: note: 'Base' has been explicitly marked deleted here
Base(const Base&) = delete;
^
Ok... fair enough. What if I try to add it back in explicitly?
class Derived : public Base {
public:
Derived() {
stuff.resize(1000);
}
void print() override {
cout << "Whatever\n";
}
Derived(const Derived&) = default;
private:
std::vector<int> stuff;
};
Then:
main.cpp:40:17: error: call to implicitly-deleted copy constructor of 'Derived'
Derived d2 = d1;
^ ~~
main.cpp:27:9: note: explicitly defaulted function was implicitly deleted here
Derived(const Derived&) = default;
^
main.cpp:18:21: note: copy constructor of 'Derived' is implicitly deleted because base class 'Base' has a deleted copy
constructor
class Derived : public Base {
^
main.cpp:14:9: note: 'Base' has been explicitly marked deleted here
Base(const Base&) = delete;
^
No joy, which also kind of makes sense. What is the solution here? Should I just ignore the original warning? Maybe I should add Base(Base&)
etc as protected
?