I have a class Node and want to declare an initially unknown number of instances of this class at run-time. First the program determines the number of nodes (num_n) from the user and then I want to define num_n objects.

I have crudely got around this by defining a maximum number of nodes and storing them in a vector so they can be accessed sequentially and edited according the the user input. But, I am wondering is it possible to use a string (e.g. n1, n2, n3...), or something else, to declare these more efficiently:

include "Node.h"

int main()
{
    int num_n;

    cout << "Enter number of nodes:\n";
    cin >> num_n;

    for (int i=0; i<num_n; i++)
    {
         // Can I declare num_n objects with names n1, n2, n3 etc?
         Node n(i) = Node();      

         // Set values of members of Node here
    }
}

I hope this makes sense as I'm not really sure what I am asking. I've tried searching the forum and google but haven't been able to find anything related to what I'm trying to do.

Thanks in advance for your help :)

Dani AI

Generated

As described, you want N Node objects created at run time and accessible later. You cannot create new C++ variable names like n1, n2 at runtime (names exist only at compile time). Instead, store the objects in a container and index or look them up by an identifier.

was on the right track (containers or dynamic allocation) and ’s idea of keeping an identifier inside the Node is useful. Which container to use depends on Node’s characteristics:

  • If Node is small and copyable, a contiguous container such as std::vector<Node> is simplest and fastest.
  • If Node is polymorphic or non-copyable/heavy, store pointers (prefer smart pointers) in a container: std::vector<std::unique_ptr<Node>>.
  • If you need lookup by an external ID (from a file), keep a map from that ID to the node (or to the node’s index).

Example pattern (uses RAII; avoids raw new/delete):

// assume Node has setId/getId or similar; Node is defined elsewhere
std::vector<std::unique_ptr<Node>> nodes;
std::unordered_map<int, Node*> byId;
nodes.reserve(num_n);

for (int i = 0; i < num_n; ++i) {
    auto n = std::make_unique<Node>();
    n->setId(parsedIdFromFile);     // set ID read from input
    byId[n->getId()] = n.get();     // store pointer to heap object (stable)
    nodes.emplace_back(std::move(n));
}

// lookup
auto it = byId.find(someId);
if (it != byId.end()) {
    Node* node = it->second;
    // use node
}

Notes and cautions:

  • Prefer smart pointers and containers (RAII) over manual new[]/delete[].
  • If you store raw pointers to elements inside a std::vector<Node> be aware that pushing more elements can reallocate and invalidate those pointers. Using heap-allocated Node objects (unique_ptr) makes the raw pointer stable even if the vector reallocates.
  • Use reserve(num_n) when you know the size to avoid repeated reallocations, validate input (non-negative, reasonable upper bound), and pick the container that matches your access patterns (sequential, random lookup, frequent insert/remove).

This approach gives runtime-determined counts, stable ownership, and efficient lookup without trying to synthesize variable names.

Recommended Answers

All 5 Replies

Why you want to declare N objects with name n1, n2, n3..nN?
It wont help you any how.

There is ways to generate name at compile time but not on runtime but still those are mainly for template programming to generate struct/class type on fly.

Can you explain why you want to do this?

anyway, if you want to give a node identifier anyway, why not change your Node class and save the node identifier

class Node{
    int identifier;
public:
    Node(int id): identifier(id){ }
}

seeing at your code looks like you already have some id to identify the object.
STL containers are mainly there to hold the unnamed objects, you wouldnt get any benefit by giving names like n1, n2..nN to all the nodes. you can identify a node using the identifier anyway.

If you explain little bit more whats your goal is, then I might give you a better example.

What you need is called dynamic memory allocation:

#include <iostream>

using namespace std;

struct Node {};

int main()
{
    int num_n;

    cout << "Enter number of nodes:\n";
    cin >> num_n;

    // Allocate memory dynamically

    Node * my_nodes = new Node[num_n];

    for (int i=0; i<num_n; i++)
    {
        // Set values of members of Node here

        // my_nodes[i] = ...
    }

    // Release memory when done

    delete[] my_nodes;
}

You could also use a vector:

#include <iostream>
#include <vector>

using namespace std;

struct Node {};

int main()
{
    int num_n;

    cout << "Enter number of nodes:\n";
    cin >> num_n;

    vector<Node> my_nodes(num_n);

    for (int i=0; i<num_n; i++)
    {
        // Set values of members of Node here

        // my_nodes[i] = ...
    }
}

Useful links:

http://cplusplus.com/doc/tutorial/dynamic/
http://cplusplus.com/search.do?q=vector

I have a finite element program and the number of nodes (also number of members, loads etc) is defined by the user and can vary from 2/3 to a few hundred... I want to allow the user to specify this information in a text file/otherwise which is read in by my program and the structure is analysed...

The names for the N objects are not important really.... they are more to show what I am trying to do....

What I need to is define these N objects during runtime (where N is specified by the user) and then be able to access these objects at different points in the program?

Thank you m4ster r0shi that's exactly what I was looking for :)

Why I always think in hard way??!!

Anyway look at the m4ster_r0sh vector example and see how he is taking input of the number of nodes and using vector to save nodes.

After saving you can access the nodes and do whatever you like.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.