Class using InterruptIn is not compiled

Hi.

I have been writing my code on mbed online compiler for a time.

Recently, I started working on mbed studio because of internet problems.

I imported a program that used to be a compile from an online computer, and there was an error when I compiled it from the mbed studio.

[Error] instanceHeader.hpp@28,28: call to implicitly-deleted copy constructor of 'HCSR04'
[ERROR] In file included from ./main.cpp:12:
./variables/instanceHeader.hpp:28:28: error: call to implicitly-deleted copy constructor of 'HCSR04'
HCSR04 sonar[NUM_SONAR] ={ HCSR04(SONAR0_ECHO, SONAR0_TRIG, SONAR_FILTER_WS,1)};
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./HCSR04_MANAGER/HCSR04.h:57:21: note: copy constructor of 'HCSR04' is implicitly deleted because field 'echo' has a deleted copy constructor
InterruptIn echo;       // echo pin
^
./mbed-os/drivers/InterruptIn.h:65:21: note: copy constructor of 'InterruptIn' is implicitly deleted because base class 'NonCopyable<mbed::InterruptIn>' has an inaccessible copy constructor
class InterruptIn : private NonCopyable<InterruptIn> {
^
1 error generated.

Has anyone solved this problem?

Hello Semin,

When an array is initialized each member is copy-initialized from the corresponding initializer-clause.

Because you have:

HCSR04 sonar[NUM_SONAR] ={ HCSR04(SONAR0_ECHO, SONAR0_TRIG, SONAR_FILTER_WS,1)};
  • First, the compiler (silently) creates a temporary object of HCSR04 by calling its constructor.

  • Then the compiler tries to assign the temporary object to the first element (member) of the sonar array by copying the temporary HCSR04 object to the memory area of the array’s first element. If there is a copy-constructor defined for the HCSR04 class it will use that one. Otherwise the compiler will define a simple “default” constructor which will copy the data members of the temporary HCSR04 object one by one. If the data member has a copy constructor then the compiler will use it otherwise will again define a simple “default” one.

  • One data member of the HCSR04 class is of InterruptIn type inheriting the NonCopyable class as you can see below:

class InterruptIn : private NonCopyable<InterruptIn> {
...
  • The NonCopyable class is in turn defined as:
class NonCopyable {
#ifndef DOXYGEN_ONLY
protected:
    /**
     * Disallow construction of NonCopyable objects from outside of its hierarchy.
     */
    NonCopyable() = default;
    /**
     * Disallow destruction of NonCopyable objects from outside of its hierarchy.
     */
    ~NonCopyable() = default;
...

That’s why we cannot define and initialize an array of NonCopyable objects and it’s children.

One solution is to define and initialize an array of dynamic objects (pointers to objects created on the heap).

For example:

HCSR04* sonar[NUM_SONAR] ={ new HCSR04(SONAR0_ECHO, SONAR0_TRIG, SONAR_FILTER_WS,1) };

and “dereferencing” the pointer before calling a member function:

sonar[0]->start();
3 Likes

Thank you for your reply Hudak.

I tried to use new operator and it works fine!

However, what I confuse about is why the online compiler compiles the same code(the array constructor one) well.

Anyway, your solution is very helpful.

Thank you!

I’m glad you solved the issue.

However, what I confuse about is why the online compiler compiles the same code(the array constructor one) well.

Copy-initialization of array members is in place since the C++17 standard. Maybe the online compiler uses an older revision where no copying is involved when an array member is initialized.

1 Like

Thank you Hudak!

Let me try to set my IDE use gcc order!