C++ serializing an object containing an array of other objects [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have the object listed below.
class Customer
{
private:
std::string customerName;
std::string customerLastName;
std::string customerIdentityNumber;
std::vector<std::unique_ptr<Account>> customerAccounts;
}
How would one go about serializing this object? I've tried finding examples but these are all using some complex libraries. Surely there must be an easier way?
Coming from Java this is new to me.

I really recommend a serialization library such as boost::serialization
Its a great library, easy to use, extremely fast, and has much more than just this!
It's exactly what you're looking for.

I prefer a very simple and basic implementation. Lets assume that Serialize() function has already been implemented for Account class.
The implementation of Serialize() function of Customer class can be:
void Customer::Serialize(Archive& stream)
{
if(stream.isStoring()) //write to file
{
stream << customerName;
stream << customerLastName;
stream << customerIdentityNumber;
stream << customerAccounts.size(); //Serialize the count of objects
//Iterate through all objects and serialize those
std::vector<std::unique_ptr<Account>>::iterator iterAccounts, endAccounts;
endAccounts = customerAccounts.end() ;
for(iterAccounts = customerAccounts.begin() ; iterAccounts!= endAccounts; ++iterAccounts)
{
(*iterAccounts)->Serialzie(stream);
}
}
else //Reading from file
{
stream >> customerName;
stream >> customerLastName;
stream >> customerIdentityNumber;
int nNumberOfAccounts = 0;
stream >> nNumberOfAccounts;
customerAccounts.empty(); //Empty the list
for(int i=0; i<nNumberOfAccounts; i++)
{
Account* pAccount = new Account();
pAccount->Serialize(stream);
//Add to vector
customerAccounts.push_back(pAccount);
}
}
}
The code is self-explanatory. But idea is to archive count and then every element. This help while deserializing from file.

Related

C++ single-function variable placement [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I'm writing a class that reads data from a file. The project is still in development, and it's likely that I'll change the file name or path later on, so I've stored it in a std::string for quicker editing.
Given that the file name is going to be used several times in a function, but is only going to be used in one function, is there a canonical cpp rule about where I should define the variable?
//don't know where I'll define this
std::string file_name = "path/to/file.foo";
//a.h file
class A {
public:
void fileFunc();
private:
//do i define it here?
};
//a.cpp file
A::fileFunc() {
//or do i define it here?
std::ifstream in(file_name);
if(in) {
//do things
}
else {
std::cerr << "couldn't open " << file_name;
}
}
Keeps all information close to thiers use.
It will help the readability and the performance. See: https://en.wikipedia.org/wiki/Locality_of_reference
So
A::fileFunc() {
const std::string file_name = "path/to/file.foo"; // pls use const when you can
...
or
A::fileFunc(const std::string& file_name) {
...
BTW, I think this should be on https://codereview.stackexchange.com/, not stackoverflow.

c++ Constructor With 1 string parameter into 3 attributes [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Some backstory...
For a homework assignment in my Data struct and algorithms,(early on) I have to create a class definition and implementation that models a store item, formatted with Part number, department code, and price. I have it mostly done except for one constructor overload that I can't seem to figure out how to start. Sample of what I have so far.
/** Default Construct*/
Item() : Part_Num("------"), Dep_Code("---"), item_Price(0){}
/** First 3Param Constructor*/
Item(std::string partNum, std::string dept, std::string priceStr):
Part_Num(partNum),Dep_Code(dept), item_Price(stod(priceStr)){}
/** Second 3Param Constructor*/
Item(std::string partNum, std::string dept, double priceD) :
Part_Num(partNum), Dep_Code(dept), item_Price(priceD) {}
The issue I have, is that I need to create a one parameter constructor that takes a string, in the format of
BN3782 ELE 87.25
and splits it into the correct data members. I have an idea for the parsing, but I don't know how to define the constructor to start. Just a push in the right direction would be appreciated. This is my first post and I'm not great at explaining, so let me know if anyone needs any additional information.
I have tried
Item(std::string data) : Part_Num(data), Dep_Code(data), item_Price(data){}
But that has yet to work with my code, and I'm not sure why it would... (was suggested on another forum).
EDIT: I got it working with pm100 suggestion, Here's a code sample I got working for anyone in the future having the same problem.
Item(std::string line) {
item_Data = line;
line = removeSpaces(item_Data);
Part_Num = line.substr(0, 6);
Dep_Code = line.substr(6, 3);
item_Price = stod(line.substr(9));
}
You need to code the field assignments
Item(std::string &valstr)
{
Part_Num = <parsed bit of string>;
Dep_Code = <a different part of the string>;
}
For the sake of completeness, if you like you can still use the initilizer list. You just need to do the parsing somewhere. Lets say you have a:
std::string nth_part(int n,std::string s) { ... }
Then your constructor could be
Item(std::string s) :
Part_Num(nth_part(0,s)), Dep_Code(nth_part(1,s)), item_Price(nth_part(2,s)) {}
However, this would require you to process the string 3 times (which you dont need if you do it in the constructor body). Using the initializer list is good practise, but not always it really pays off.
Item(std::string data)
{
int i=0;
int counter=0;
std::string temp="";
int len=data.length();
while(i<len)
{
if(data[i]!=' ' && i<len-1)
{
temp+=data[i];
}
else
{
if(counter==0) Part_Num=temp;
else if(counter==1) Dep_Code=temp;
else
{
temp+=data[i];
item_price=stod(temp);
}
++counter;
temp="";
}
++i;
}
}
this will give you the desired result for your problem, you can check it by running.

How can I (cleanly!) subclass std::stringstream for a customization? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a logging class with a std::stringstream member. I use it's output << overloading to get a nice easy means for catching all the data types std::stringstream gives me for free.
Here's the problem. After sending data into the stream, I want an easy way to flush it automatically to my destination (which is variable/dynamic in nature).
std::ostream will "auto flush" if you send an endl down it. That's and acceptable solution I would duplicate.
How can I implement that myself? Note that I don't want to override every operator<<() overload in std::stringstream!
I've done a similar thing. What I do is use an unnamed class instance to consume the output and put the flushing in the destructor. Something like this:
int i = 0;
MyClass() << "This is a log message containing an int: " << i;
// here, the class destructs and does whatever you need to do to flush the stream
Instead of subclassing std::stringstream, it's prefered to use composition (see Composition over inheritance).
With this, your class would look like this:
class Log{
std::stringstream _stream;
[...] // Constructor and other class logic
public:
Log& operator<<(string s){
_stream << s << endl;
return *this;
}
};

Load big file asynchronously using c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Hi I dnt have any knowledge on Multithreading or Parallel programing.
I need to load multiple file for an application, in which the load time does not affect the application or response to user.
I used CreateThread with that I cannot able to load data to a class variable.
Any guidance of how to do this in VC++ will be a great help.
Thanks in Advance !!
For example,
My application is streaming content meantime I need to load a big image to to class variable (Bitmap), which should not affect the streaming i.e without pause.
Modern C++ allows you to use hi level abstract features such as std::future:
struct Data {
// file name just for info
std::string file_name;
// here is data from file ...
static Data load(const std::string& name) {
Data data{ name };
// todo load from file
return std::move(data);
}
};
std::vector<std::string> names = { "file1.txt", "file2.txt", "file3.txt" };
std::vector<std::future<Data>> results;
for (const auto& name : names) {
// load from the name file asynchronously
auto future = std::async(std::launch::async, &Data::load, std::ref(name));
results.emplace_back(future);
}
// gather result
for (auto& future : results) {
Data& data = future.get();
// todo use data from the file object
}

c++ using scope resolution operator in function call parameter [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Can someone please point me to an explanation what e.g. QIODevice::WriteOnly actually does?
full line of code:
file.open(stderr, QIODevice::WriteOnly);
from that link
thanks
According to the documentation for the QIODevice class, WriteOnly is as enum constant with value 2. It indicates that the device is open for writing.
I believe that the following example for enum hack will be useful to you.
class MyClass1 {
public:
enum { SIZE=10 };
};
class MyClass2 {
public:
enum { SIZE=20 };
};
int main() {
cout << MyClass1::SIZE << "\t" << MyClass2::SIZE << endl;
}
QIODevice::WriteOnly is just a flag, you're saying that you want to open the file only for writing.
If you would want only to read the file, QIODevice::ReadOnly would be the necessary flag to use.
And to read and write use flag: QIODevice::ReadWrite:
file.open(stderr, QIODevice::ReadWrite);