Reputation: 6031
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
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
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