Masoud Rahimi
Masoud Rahimi

Reputation: 6031

Call member constructor in copy constructor definition

I'm trying to understand the copy constructor in c++ and I want to define my own copy constructor as I have a pointer member in my class so I need a deep copy. Suppose this:

communicate.h:

#ifndef communicate_h
#define communicate_h

#include "mbed.h"

class Communicate
{
private:
    /* data */
    BufferedSerial serial;
    FILE *serial_stream;
public:
    Communicate(const PinName Tx, const PinName Rx, const int baud);
    Communicate(const Communicate& source);
    ~Communicate();
};
#endif

communicate.cpp:

#include "communicate.h"


Communicate::Communicate(const PinName Tx, const PinName Rx, const int baud): serial(Tx, Rx, baud)
{
    serial.set_blocking(false);
    serial_stream = new FILE;
    serial_stream = fdopen(&serial, "w+");
}

Communicate::~Communicate()
{
    delete serial_stream;
}

// copy constructor
Communicate::Communicate(const Communicate& source)
{
    serial = source.serial;
    serial_stream = new FILE;
    *serial_stream = *source.serial_stream;
}

And I get this:

Compile [ 99.5%]: communicate.cpp
[Error] communicate.cpp@17,51: no matching function for call to 'mbed::BufferedSerial::BufferedSerial()'
[Error] communicate.cpp@19,21: use of deleted function 'mbed::BufferedSerial& mbed::BufferedSerial::operator=(const mbed::BufferedSerial&)'
[Error] BufferedSerial.h@52,7: use of deleted function 'mbed::SerialBase& mbed::SerialBase::operator=(const mbed::SerialBase&)'
[Error] SerialBase.h@46,7: use of deleted function 'mbed::NonCopyable<T>& mbed::NonCopyable<T>::operator=(const mbed::NonCopyable<T>&) [with T = mbed::SerialBase]'
[Error] SerialBase.h@46,7: non-static const member 'const PinName mbed::SerialBase::_tx_pin', can't use default assignment operator
[Error] SerialBase.h@46,7: non-static const member 'const PinName mbed::SerialBase::_rx_pin', can't use default assignment operator
[Error] BufferedSerial.h@52,7: use of deleted function 'mbed::FileHandle& mbed::FileHandle::operator=(const mbed::FileHandle&)'
[Error] FileHandle.h@46,7: use of deleted function 'mbed::NonCopyable<T>& mbed::NonCopyable<T>::operator=(const mbed::NonCopyable<T>&) [with T = mbed::FileHandle]'
[Error] BufferedSerial.h@52,7: use of deleted function 'mbed::NonCopyable<T>& mbed::NonCopyable<T>::operator=(const mbed::NonCopyable<T>&) [with T = mbed::BufferedSerial]'
[Error] BufferedSerial.h@52,7: use of deleted function 'rtos::Mutex& rtos::Mutex::operator=(const rtos::Mutex&)'
[Error] Mutex.h@70,7: use of deleted function 'mbed::NonCopyable<T>& mbed::NonCopyable<T>::operator=(const mbed::NonCopyable<T>&) [with T = rtos::Mutex]'

The error complains about not calling the constructor of BufferedSerial class in the copy constructor of Communicate class and on the other hand, I can't simply put the : serial(Tx, Rx, baud) in front of copy constructor definition.

I'm not sure how to call the member constructor in the copy constructor definition.

Upvotes: 1

Views: 79

Answers (2)

t.niese
t.niese

Reputation: 40842

The error message tells you that BufferedSerial is not copy assignable:

[Error] communicate.cpp@17,51: no matching function for call to 'mbed::BufferedSerial::BufferedSerial()'
[Error] communicate.cpp@19,21: use of deleted function 'mbed::BufferedSerial& mbed::BufferedSerial::operator=(const mbed::BufferedSerial&)'

At the end of the error message you see:

[Error] Mutex.h@70,7: use of deleted function 'mbed::NonCopyable<T>& mbed::NonCopyable<T>::operator=(const mbed::NonCopyable<T>&) [with T = rtos::Mutex]'

A class is only default copy construct and copy assignable if all its members are. Due to how a mutex works, it is not copyable, and because mutex is used by one of the members of BufferedSerial the BufferedSerial itself won't be copy construct and copy assignable by default, and your Communicate shouldn't be either due to that.

If you want to write a copy constructor and copy assignment operator for your class, then you need to figure out how you can have two distinct FILE that work on the same file/pipe, which normally does not make much sense (or how to share them between instances). Because if you do that, especially with a w+ you most certainly run into problems with data corruption if the stream is buffered (another reason why it would most certainly not be copyable even if mutex is not used).

This indicates that you might have a misconception in your design.

Upvotes: 2

Giogre
Giogre

Reputation: 1504

I believe the error is in the first line in the body of your copy constructor, on the right hand side: given that serial is a private element of the class, you cannot access serial from the Communicate object you set to copy from. You need to define some get() function and copy from it.

Upvotes: 0

Related Questions