简体   繁体   中英

How to write a C++ constructor with same signature as copy constructor?

I am writing a class that can optionally have a reference to its parent. In other words the class looks something like this:

class X {
    const X* parent;
public:
    // (1) Default constructor with no parent 
    X() : parent(nullptr) {}
    // (2) Constructor that accepts a parent
    X(const X& parent) : parent(&parent) {}
};

The problem is that constructor 2 is the copy constructor, but it's not working as a copy constructor.

Obviously I could just have constructor 2 take a pointer. Another solution could be to make a static method to construct a new X and set its parent member.

Every solution has annoying drawbacks:

  • Possibly constructor does something with parent so if I passed it as a pointer I'd have to handle the nullptr case at runtime.
  • If I create a static function to initialize an X with a parent, then I have to make X copyable or moveable.

Is there a standard idiom or pattern for dealing with this situation?

You can use tag dispatching to handle this by creating a tag type that you using to signal you want the construct with pointer to parent behavior instead of copy construction. That would look like

struct parent_reference {};

class X {
    const X* parent;
public:
    // (1) Default constructor with no parent 
    X() : parent(nullptr) {}
    
    // (2) Constructor that accepts a parent
    X(parent_reference, const X& parent) : parent(&parent) {}
            
    // (3) Copy Constructor
    X(const X& that) = default;
};

X a;                       // default
X b(a);                    // copy
X c(parent_reference{}, b) // b is now the parent of c

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM