1

How to properly use a class object (serial) inside my class (UART) object?

The class object that I want to copy has its copy constructor declared in "Private" and my compiler says:

‘serial::Serial::Serial(const serial::Serial&)’ is private within this context
     UART::UART(const serial::Serial& serial_port) : _serial(serial_port), _letter(" ") {}

And the definition of

serial::Serial::Serial(const serial::Serial&)

is:

private:
  // Disable copy constructors
  Serial(const Serial&);

This is my class header file:

 class UART
    {
    private:
        serial::Serial _serial;
    public:
        UART(const serial::Serial& serial_port) : _serial(serial_port) {};
        ~UART();
        bool read(std::string &data);
        bool write(std::string &data);
    };

As you can see, I have declared a class object called _serial and I just want to use this object inside UART class and I usually do this by copy construction method (passing serial object to the construction of UART and copy it)

So if the serial class does not allow a copy constructor (because it has been declared in the private section) how can I copy it (or may be other approach?) and use this object inside my UART class?

aikhs
  • 949
  • 2
  • 8
  • 20
  • Looks like an embedded (micro con) system. There are many trickeries involved. Full definition of serial class is needed. Whether or not the serial instances are placed at memory mapped io ports, is of great relevance. Otherwise, any answer would be misleading. Plz mention your platform(hardware+toolchain) before anything else. – Red.Wave Apr 03 '19 at 17:06

2 Answers2

0

how can I copy it

You cannot, but you may be able to move it (unlikely, from what you say, this looks like pre-C++11 code).

or may be other approach?

Either don't copy (for instance, keep a pointer or reference to it), or construct a new serial object, or instead of copying it, pass it by reference/pointer to the methods that need it.

Acorn
  • 24,970
  • 5
  • 40
  • 69
  • Why do you think it is pre-C++11? I am using C++11. I believe you mean the serial class definition is pre 11? – aikhs Apr 03 '19 at 15:55
  • @Edmund It was just a guess from the fact that you did not mention move constructors and that the `Serial` class doesn't use `= delete` to disable the copy constructor. – Acorn Apr 03 '19 at 15:59
  • but if I would use std::move, how is it going to affect the serial port communication? As the first (original) serial object will become rvalue – aikhs Apr 03 '19 at 21:23
  • The object needs to support move semantics. The actual serial communication should not be affected at all if done properly. What would happen is that the `Serial` object is now owned by you, and the original one is empty (you "consumed" it). In the end, you need to decide who owns the object, or maybe you really need shared ownership (e.g. `std::shared_ptr`), but that is rare. – Acorn Apr 04 '19 at 17:56
0

Presumably, the Serial class disables copying because it represents a physical device; copying the object would break communication to the device because the copy would not know the state of the original object.

If UART should own the Serial object, you can probably std::move it into the UART constructor. Otherwise, you probably want to just hold a pointer or reference to the Serial object.

class UART
{
private:
    serial::Serial& _serial;
public:
    UART(serial::Serial& serial_port) : _serial(serial_port) {};
    // etc.
};

Be aware of object lifetimes; if your UART object outlives your Serial reference, then dereferencing the destroyed object will lead to Undefined Behavior.

0x5453
  • 12,753
  • 1
  • 32
  • 61
  • And how can I be sure to dereference UART object before destroying Serial object? Shall I call the destructor manually inside my code when I will be done with the UART class? – aikhs Apr 03 '19 at 15:45
  • @Edmund Why do think, you need to destroy it, when it's a reference to an object? – Algirdas Preidžius Apr 03 '19 at 16:00
  • @Edmund If you are not the owner, you mustn't destroy it. – Acorn Apr 03 '19 at 16:01
  • @AlgirdasPreidžius How else can I ensure to free the pointer from the memory before destroying the object that the pointer if referencing to? – aikhs Apr 03 '19 at 16:06
  • @Acorn What I mean is to free the pointer which is referencing to the object, not the object itself – aikhs Apr 03 '19 at 16:06
  • @Edmund I am sorry, but, what? Free which pointer? You don't do anything, for the same reason, as you don't call `delete` in `pi` in following code snippet: `int i = 5; int* pi = &i;`, or don't need to do any explicit cleaning in `int i = 5; int& ri = i;`. – Algirdas Preidžius Apr 03 '19 at 16:10
  • @AlgirdasPreidžius So the C++ smart enough to clean up everything itself? But that is the case only when both pointer and the variable in the same program. What happens when the variable is being started by a different main and finishes before the main with the pointer finishes? Then I guess it won't clean up . – aikhs Apr 03 '19 at 16:20
  • @Edmund 1) It's not that it cleans everything by itself. It cleans up variables allocated with automatic/static/thread storage location. Only variables with dynamic storage duration need to be deallocated manually. 2) "_What happens when the variable is being started by a different main_" What do you mean by this? There can only be a single `main` in a single program. 3) Consider learning C++ from a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), since your questions seem to be devolving into questions about C++ fundamentals. – Algirdas Preidžius Apr 03 '19 at 16:29
  • @AlgirdasPreidžius I do know fundamentals and it seems to me that you are having trouble to understand the problem. Two mains means two programs executed at two different CPP files. So you are not correct saying that you do not have to deallocate memory as it will lead to memory leak – aikhs Apr 03 '19 at 19:32
  • @AlgirdasPreidžius If you point a pointer to an object which has been initialized in a different CPP file and that object will be destroyed earlier (because that CPP file ended earlier) your pointer which has been initalized in a different file (meaning in a different main) will then have UB. – aikhs Apr 03 '19 at 19:33
  • @AlgirdasPreidžius Pardon me, when I say deallocate the pointer I mean to reference the pointer to something else before the object (which the pointer points to) is being destroyed. Of course you cannot deallocate (destroy) pointer in stack. – aikhs Apr 03 '19 at 19:43
  • @Edmund Your comments seem to contradict the notion of you knowing fundamentals. There's no such thing, as cpp file ending earlier, than another, due to the fact, that compiled program does not preserve such information. Yes, you can link two (or more) object files together, compiled from multiple .cpp files together, but the entire application can only contain one `main` function. Execution of which starts by entry of the `main` function, and terminates, typically, by exit of it. What you do inside the `main` is what the program does, which typically includes calls to other functions. – Algirdas Preidžius Apr 03 '19 at 20:14
  • @Edmund Because I need to explain how is C++ program executed, it is clear that you don't have a grasp on the fundamentals. Since this topic, is, typically, explained in the first chapter of a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Because of that, I will not reply to any of your further comments. – Algirdas Preidžius Apr 03 '19 at 20:15
  • @AlgirdasPreidžius I think you are just grabbing the words instead of replying to the question. You are again referring to main as the actual main in the CPP file. Without making sure that the pointer points to a different object before the previous object is being destroyed, it will be UD. Period. – aikhs Apr 03 '19 at 20:16
  • @AlgirdasPreidžius So I think your lack of knowledge in C++ makes you just explaning the basic concepts even though there is no problem related to it. – aikhs Apr 03 '19 at 20:17