2

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 :-)

awesomefireduck
  • 395
  • 1
  • 3
  • 10

5 Answers5

4

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!

Jaka Konda
  • 1,385
  • 3
  • 13
  • 35
2

Yes.

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

celticminstrel
  • 1,637
  • 13
  • 21
2

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.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
1

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++;
}
Community
  • 1
  • 1
Captain Giraffe
  • 14,407
  • 6
  • 39
  • 67
1

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.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Plus 1 for the commentary about constness. However, it *can* be misunderstood. So I'm pointing out to readers (this sentence) that the two declarations are not equivalent, at all, and were not meant to be equivalent. – Cheers and hth. - Alf Jun 23 '15 at 00:41