-1

I have created this structure:

struct xlsmain {
    vector<sub_parts> sb;
    string name;        
}

struct sub_parts {
    vector<pio_parts> pio;
    string name_pio;
    string direction;
    string partition;
}

struct pio_parts {
    string pio_name;
    vector<report_specs> report;
}

struct report_specs {
    string name; 
    vector<string> value;
}

struct xlsmain* interface = new xlsmain[100];

The nesting is necessary because every element is related in a heirarchial manner. The problem I am facing right now is how to enter values in this structure.

EDIT: I don't like using push_back() because every time I'll have to declare a separate structure. So for instance if I want to add a sub part to xlsmain, I have to declare a variable:

sub_parts sb1;

Then I have to feed values into this structure until it is finished, when I can use:

interface[i].sb.push_back(sb1);

Further, if nesting is involved then a number of structures like sb1 will also have to be created. This leads to having to create a large number of variables just to enter even a single value in my structure.

Cprog
  • 67
  • 1
  • 1
  • 5
  • You don't need the `struct` keyword in front of xlsmain* unlike in C – daniel gratzer Oct 19 '12 at 06:04
  • 1
    You have 4 levels of nesting, I can't see how it can't be complex. – Luchian Grigore Oct 19 '12 at 06:04
  • nesting may be increased to 4 more levels as i proceed in my project. instead of vectors if i use array processing becomes easier but then i face memory issues – Cprog Oct 19 '12 at 06:07
  • Where do you enter the values from? – Andriy Oct 19 '12 at 06:11
  • I think you need other approach to represent store your data – Denis Ermolin Oct 19 '12 at 06:11
  • i have to process thousands of files,get some specific data from these files and store it here – Cprog Oct 19 '12 at 06:12
  • i am not able to figure out any other solution here because each information is related to other in heirarchy – Cprog Oct 19 '12 at 06:13
  • 1
    Where is the `push_back()` part? you have a dynamic array of `xlsmain` objects, not a list or a vector. – PaperBirdMaster Oct 19 '12 at 06:25
  • for storing values in `interface[i].sb` `push_back()` have to be used – Cprog Oct 19 '12 at 06:29
  • You have a vector and you use `push_back` to add elements. What is so complex about that? – jogojapan Oct 19 '12 at 06:36
  • For using `push_back()` every time i'll have to declare a separate structure for eg `sub_parts sb1` and feed values into this structure and then use `interaface[i].sb.push_back(sb1)` . Further if nesting is there then a number of structure like `sb1` will have to be created. This leads to dealing of number of variables when i enter even a single value in my structure. – Cprog Oct 19 '12 at 06:53

2 Answers2

0

Before the edit, your concern that push_back() was "too complex" wasn't clear. (It sounded like perhaps even you didn't like the name of the method...or something strange like that?)

I'll try to get to addressing the new issue raised. But I will reiterate that although you are using the standard library string and vector classes, your structures are not themselves getting the advantages of C++!

You don't have constructors, destructors, or methods. Those are the foundations of letting data objects "come alive" with "magic" behavior that lets clients of these classes write simpler, more abstract code. This is helpful even if your only "client" is just more of your own code!

Let's say before you had code like:

pio_parts pp;
pp.pio_name = "this string will be stored in the name";
pp.report.push_back(someReport);
pp.report.push_back(anotherReport);

If you add a constructor and a method to your structure, like this:

struct pio_parts {
    string pio_name;
    vector<report_specs> report;

    pio_parts(string newName) {
         pio_name = newName;
    }

    void addReport(report_specs newSpecs) {
         report.push_back(newSpecs);
    }
};

Then the code above gets nicer:

pio_parts pp ("this string will be stored in the name");
pp.addReport(someReport);
pp.addReport(anotherReport);

Though really, you've not done much than save yourself from having to know the name of the data member in pio_parts to add to. Now you remember a method name instead. You save a little typing, but push_back() was about as good.

HOWEVER if there were more related operations you need to do inside of addReport() than just add to the vector, you now have a place to put all that code. That way the user of your class can not worry about whatever bookkeeping is necessary to add a report...they just ask that it be done! Also, since there's no call to push_back() it's no longer necessary for whoever is calling addReport() to know that the list is being stored in a vector.

I've deliberately not even bothered to try and scratch deeper into the specifics of references, copy-construction, smart pointers, member initialization syntax, or even class vs struct. It's too deep a language. Take a time out ASAP and carefully read this short paper by Bjarne Stroustrup that lays out that clear contrast in methodology:

Learning Standard C++ as a New Language


Now I'll try to get on to your other concern. First of all, you do not have to create a named instance of a variable in C++ to pass it to a function. You can rewrite:

sub_parts sb1;
interface[i].sb.push_back(sb1);

...as instead:

interface[i].sb.push_back(sub_parts ());

Not particularly useful in this case, as the object is constructed empty...so you just pushed something useless. But if your constructor took parameters that filled the object, it would be fine. You can even build up arrays like this:

How can I initialize an array of objects whose constructor require two or more arguments?

But if your constructor takes a hardcoded list (as yours seem to), then there's been a bit of a fly in the ointment. While C++ can initialize ordinary arrays with values you code in directly, passing the ordinary array loses its length information. A vector would be better, but initializing them with hardcoded values is clunky:

What is the easiest way to initialize a std::vector with hardcoded elements?

You can see that people had pretty much the same complaint you did about having to write:

std::vector<int> ints;

ints.push_back(10);
ints.push_back(20);
ints.push_back(30);

That post lists some of the workarounds, but bleeding edge compilers (probably not what you're using) support:

std::vector<int> ints = {10, 20, 30};

Once you have those, it makes it extremely easy to do your "nested" style constructions.


As a final note: you seemed on an earlier comment to concretely ask about raw arrays vs vectors. For your interface you almost certainly want a vector. Here's a pitfall: using new xlsmain[100] on a raw array requires to remember to do a delete[] interface (and not just a regular delete interface):

delete vs delete[] operators in C++

Bear in mind there is also no realloc in C++ anyway. So if that's why you were dynamically allocating it, forget about that idea.

You can save yourself from trouble like this by just making interface a vector. You will be able to resize it if you ever need to, and also avoid hard-coding a so-called "Magic Number" into your program.

Community
  • 1
  • 1
  • Sorry for bothering you so much but i donot know c++ programming. Just because in my previous question, i was suggested to use vectors instead of arrays so I did read the VECTOR part but got stuck because of the nesting. Also, the code is quite long to put it up here. Thank you for your help. – Cprog Oct 19 '12 at 07:15
  • Well, no one is holding a gun to my head to make me answer. :-) I do like to try and practice my explanation skills, as well as to try and make sure people get a chance to improve their question-asking skills. But it helps when people listen! I will try and update to address the comment I integrated, which builds on the rest of what I said...so still, go read the Stroustrup paper!! – HostileFork says dont trust SE Oct 19 '12 at 07:25
0

An option would be to use a std::map instead of the vector, then you can do something like this

xmlsmain["some element"].sb["some other"].direction = "up";

In this way, elements "some element" and "some other" are automatically created.

Dirk
  • 1,789
  • 2
  • 21
  • 31