Making an INonCopyable class

Hi

Consider the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <vector>
#include <cstddef>


class INonCopyable
{
  private:
  INonCopyable() = delete;
  INonCopyable& operator=(const INonCopyable&) = delete;
};

class Base : INonCopyable
{
  protected:
    int moo = 34;
};

class Child : Base
{
  public:
  void printMoo()
  {
    std::cout << moo << '\n';
  }
};

int main()
{

  Child c;

  c.printMoo();

  return 0;
}

(Note: The code works fine when Base dont derive from INonCopyable)

I dont want you to be able to create a base object, only derive from it.
But when i make Base derive from INonCopyable (Like in the example) i get the following error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mainer.cpp: In function ‘int main()’:
mainer.cpp:31:9: error: use of deleted function ‘Child::Child()’
   Child c;
         ^
mainer.cpp:19:7: note: ‘Child::Child()’ is implicitly deleted because the default definition would be ill-formed:
 class Child : Base
       ^
mainer.cpp:19:7: error: use of deleted function ‘Base::Base()’
mainer.cpp:13:7: note: ‘Base::Base()’ is implicitly deleted because the default definition would be ill-formed:
 class Base : INonCopyable
       ^
mainer.cpp:9:3: error: ‘INonCopyable::INonCopyable()’ is private
   INonCopyable() = delete;
   ^
mainer.cpp:13:7: error: within this context
 class Base : INonCopyable
       ^
mainer.cpp:13:7: error: use of deleted function ‘INonCopyable::INonCopyable()’
mainer.cpp:9:3: note: declared here
   INonCopyable() = delete;


How come? whats wrong?

Thanks in advance
How come?
Because the default constructor is explicitly deleted: INonCopyable() = delete;

Try something like this:

1
2
3
4
5
6
7
struct noncopyable { 
  noncopyable(noncopyable const&) = delete;
  noncopyable& operator=(const noncopyable) = delete;
protected:
  ~noncopyable() = default; 
  noncopyable() = default;
};


Note the destructor is protected, non-virtual. The alternative would be to make it public, virtual, so that users could delete sub-classes through a pointer or reference to noncopyable.
Last edited on
You could make Base an abstract class by declaring a pure virtual function in it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

class Base {
protected:
    int moo = 42;
public:
    virtual void printMoo() = 0;
};

class Child : public Base {
public:
    void printMoo() {
        std::cout << moo << '\n';
    }
};

int main() {
    Child c;
    c.printMoo();
//    Base b; // cannot declare b to be of abstract type Base
    return 0;
}

Last edited on
I dont want you to be able to create a base object, only derive from it.


To do that, one way is to make all the constructors protected, or even private if possible. Another way is to have one of the functions in Base pure virtual.

The presence of the I in INonCopyable is a convention that the class is some sort of interface. So the idea of not being able to instantiate it applies to it as well as the Base class.

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#S-interfaces
Topic archived. No new replies allowed.