0

I'm not sure how I should word this, so I'll attempt to put it in code. (This has many errors I know it will not compile it is simply to show what I want to do because I can't put it in words)

    using namespace std; //for correctness sake
    class foo {
    public:
        foo(int a=0, int n=0);
        void stuff(int a);
        void function(int n);
        const int get_function() {return n;}
        const int get_stuff(){return a;}
    private: 
       int n, a;
    };
    struct Store{
        public: get_foo(){return vector<f.foo>;} //I'm not too sure of the syntax here but you get the idea
    private: 
        foo f;

    }

Basically I want to take all the information that is returned in class foo, and output this, formatted, to a file. Thing is, I need to make many of these within the file and it has to be able to read it back for it to be worth anything. So just appending each consecutive foo class to the file won't work(at least I don't see how).

I tried using ostream to overload the << operator, but I'm not sure how to call it to write it to the file. Any suggestions are welcome! Thanks.

Shilaly
  • 23
  • 1
  • 1
  • 8
  • Note: `const get_function() {return n;}` is not standard-compliant C++. The language requires a type-specifier for all declarations. This (as well as `get_stuff()`), should be declared with `int`. Decide for yourself whether you think `const` is warranted (it isn't). – WhozCraig Oct 03 '13 at 06:16
  • @WhozCraig You're right I forgot the function type, I used const because that's what I've seen in class for examples. – Shilaly Oct 03 '13 at 06:22
  • I highly suspect the declaration should be `int get_function() const { return n; }`, since the member has no requirements to modify the object. – WhozCraig Oct 03 '13 at 06:25

3 Answers3

2

I think your Store should be like this:

struct Store
{
public:
    std::vector<foo> get_foo()
    {
       return f;
    }

private: 
    std::vector<foo> f;
};

To overload << of std::ostream:

std::ostream& operator<<(std::ostream& out, const Store& f)
{
  for (auto &x : f.get_foo())
    out << x.get_function() << ", " << x.get_stuff() << "\n";

  return out;
}

//Without auto

std::ostream& operator<<(std::ostream& out, const Store& f)
{
  std::vector<foo> q = f;
  for (int i=0; i<q.size(); i++)
    out << q[i].get_function() << ", " << q[i].get_stuff() << "\n";

  return out;
}
masoud
  • 55,379
  • 16
  • 141
  • 208
  • Thanks for the reply, Could you explain the x to me? I am confused why it's x.get_function and not of the foo class. Sorry, I am unfamiliar with how `auto` and several c++11 features work in these cases. – Shilaly Oct 03 '13 at 06:38
  • @M M. Ahh thanks, I think I see what it's doing now. It basically condenses the iteration(probably much simpler than it really is). Are there any advantages to using auto in this instance as opposed to incrementing i to move through the vector? – Shilaly Oct 03 '13 at 06:54
  • @Shilaly: It syntax sugar. Makes code smaller, more clear and more general. – masoud Oct 03 '13 at 07:00
1

There are many tings wrong with your code.

So many that it's clear that you never read any C++ book and are just experimenting with a compiler.

Don't do that. C++ is really the worst language in the world to approach that way for many independent reasons.

No matter how smart you are.

Actually being smart is sort of a problem in certain areas because many C++ rules are not the result of a coherent logical design, but of historical evolution and committee decisions. Not even Hari Seldon would be able to foresee correctly what a committee would decide, you cannot deduce history.

Just pick a good book and read it cover to cover. There is no other sensible way to learn C++.

About writing structs to a file the topic is normally called "serialization" and takes care of the slightly more general problem of converting live objects into a dead sequence of bytes (written to a file or sent over the network) and the inverse problem "deserialization" of converting the sequence of bytes back into live objects (on the same system, on another identical system or even on a different system).

There are many facets of this problem, for example if your concern is about portability between systems, speed, size of the byte sequence, ability to reload bytes sequences that were saved back when your classes were slightly different because you evolved the program (versioning).

The simplest thing you can do is just fwrite things to a file, but this is most often simply nonsense in C++ and is a terrible way for many reasons even when it's technically possible. For example you cannot directly fwrite an std::vector object and hope to read it back.

Community
  • 1
  • 1
6502
  • 112,025
  • 15
  • 165
  • 265
  • Yes that code won't compile I know, that's not what I'm trying to compile, I wouldn't have written any code if I could have said that in words. The point of the code in my question is not to be perfect, it's to visualize what I'm trying to do with my classes. I'd like to do this with c++ because I'm trying to learn c++. – Shilaly Oct 03 '13 at 06:27
  • 1000% agreed with above said. @Shilaly - even if you find it boring to read a book, you can find lots of samples how to do it on Internet. Some of them will even compile. – SChepurin Oct 03 '13 at 07:01
  • @SChepurin Well this wasn't my first resort believe it or not. I did many searches for "write a vector of structs to a file" and couldn't find any anywhere near applicable. If you could point me to some that I clearly missed, that would be appreciated. Also, a side note, a lot of the code you find in Stroustrup's book doesn't compile. I perfectly understand the idea of what I want to do, the syntax is what perplexes me. – Shilaly Oct 03 '13 at 07:12
  • @Shilaly - It is not so easy task to implement as it seems, there are libraries created only for this purpose (in Boost, for example). As for the question, take a look on what other people tried - http://stackoverflow.com/questions/709297/what-am-i-doing-wrong-with-my-serializing-a-vector-with-structs-in-it-to-a-dat – SChepurin Oct 03 '13 at 08:10
0

I think you need something like this:

template<typename T>
std::ostream& operator << (std::ostream& out, const std::vector<T*>& elements)
{
  for (size_t i = 0; i < elements.size(); i++)
    out << elements[i] << ", ";
  return out << std::endl;
}
Ilya
  • 4,583
  • 4
  • 26
  • 51
  • Thanks, I've not yet worked with templates, so I will look into templates and try out your suggestion. Do you recommend any reference in particular, or will a Google search suffice? – Shilaly Oct 03 '13 at 06:40