简体   繁体   中英

c++ extend constructor of same class (no inheritance)

I might have found my answer somewhere here, but nevertheless, I'd like to be sure.

I am making something represented in a graph (hence the nodes), and I wondered if this code of the constructors is working the way I think.

G++ doesn't complain.

I have the following class:

#ifndef viper_node
#define viper_node

#include "../globals.hpp"

#include <vector>
/**
 * @brief The base class for the nodes
 */
class Node {
public:
    /**
    * @brief base constructor for the node
    */
    Node();

    /**
    * @brief exteded constructor for the node
    * @param [in] parent_p the pointer to the parent of the new node
    */
    Node(Node*const& parent_p);
    /**
    * @brief extended^2 constructor for the node
    * @param [in] parent_p the pointer to the parent of the new node
    * @param [in] name the name of the node
    */
    Node(Node*const& p, std::string const& name);
    /**
    * @brief base destructor
    */
    ~Node();

protected:
    /// pointer to the parent node of this one (nullptr if rootnode)
    Node* parent;

    ///pointers to the children
    std::vector<Node*> children;

    ///the name of the class/func/var (ex: children)
    std::string name;

    ///description of the name/func/var (ex: pointers to the children)
    std::string description;

    ///the properties of the node (static, private,...)
    uint flags;

    /// the type of the node (function, variable, binary, etc.)
    nodeType node_type;

    ///the scope of the node (global, class member, function local)
    nodeScope scope;

    unsigned long get_id() {return id;};

private:
    ///the id of the node (unique)
    unsigned long id;

    ///to keep track of the next unused id
    static unsigned long maxID;

};

#endif

and the following definitions:

#include "node.hpp"

unsigned long Node::maxID = 0;

Node::Node()
{
    parent = nullptr;
    flags = 0;
    id = maxID++;
}

Node::Node(Node*const& parent_p) : Node::Node()
{
    parent = parent_p;
}

Node::Node(Node*const& p, std::string const& Name) : Node::Node(p)
{
    name = Name;
}

Node::~Node()
{
    parent = nullptr;
    for (auto it : children)
    {
        delete it;
    }
}

My question is this:
If I call Node(parent_p,"name") , is the function preceded by Node(parent_p) which is itself preceded by Node() ?

Thanks for the help :-)

Yes you can as of C++11 standard. Wiki article .

Also a quick empirical verification:

using namespace std;

class A
{
    public:
    A()
    {
        cout << "Hello "; 
    }

    A(int x) : A()
    {
        cout << "World!" << endl;
    }
};

int main()
{
    A a(1);


    return 0;
}

Prints:

Hello World!

Yes.

This is something known as "delegating constructors" which was introduced in C++11 (the revision of the language completed in 2011).

Yes, you can delegate to other constructors since (and including) C++11.

With C++03 you had to resort to other means such as init functions and artificial dummy base classes.

C++11 also introduced inheritance of constructors, with a using declaration, reducing the amount of boilerplate for common simple situations.

This is an interesting read.

It might be of interest that delegating constructors is commonly used in the opposite direction.

#include "node.hpp"

unsigned long Node::maxID = 0;

Node::Node():Node(nullptr)
{
}

Node::Node(Node*const& parent_p) : Node(parent_p, "")
{
}

Node::Node(Node*const& p, std::string const& Name)
{
    parent = p;
    name = Name;
    flags = 0;
    id = maxID++;
}

Also this particular case can easily be implemented with default arguments.

Node::Node(Node*p = 0, std::string const& Name = "")
{
    parent = p;
    name = Name;
    flags = 0;
    id = maxID++;
}

They are so-called delegating constructors. They delegate the class construction to other constructors. If a constructor is used such a way it shall be the only initializer in the mem-initializer list.

Take into account that there is no great sense to declare a constructor such a way as this constructor

Node(Node*const& parent_p);

There is more sense to declare it simply like

Node( const Node *parent_p );

Otherwise it looks like the node pointed to by parent_p can be changed inside the constructor.

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