So I am trying to do something, but I am not sure it can/should be done this way in c .
I have a file of objects I want to read in. Each object is of one of 3 types of classes which are part of a hierarchy
In the file I have a discriminator to tell me which is which.
Lets say the classes are:
Checking, Savings and are subclasses of Account.
Can i build code such that:
Account a;
istream >> a;
Will let me polmorphically set the resulting data in a to the appropriate type ? ( i realize the code would have to be there to do it)
Hope that makes sense. Or, do i just need a "deserialize" method or something that i don't use operator overloading for?
I can't use any existing non STL libraries out there, as this is for a classroom example.
Thanks!
Edit: I think my question may have been unclear:
friend istream& operator>>(istream& is, Transactions& transactions)
{
is my function, and i want to have transaction set to a subclass of Transaction....
I'm thinking this isn't possible without some of the new newer features some have mentioned?
CodePudding user response:
C does not work this way, on a fundamental level. Quoting from your question, if you have a declaration:
Account a;
Then that's what a
is. In C , the types of all objects must be known at compile time. This is fundamental to C , there are no exceptions or workarounds. The type of a
cannot be changed at runtime, based on some arbitrary criteria.
Will let me polmorphically set the resulting data in a to the appropriate type ?
Nope. a
is an Account
. This is immutable, and cannot be changed based on runtime conditions.
Or, do i just need a "deserialize" method
That would be a very common approach, and was pretty much the rule of the land before C 17.
In C 17 you could declare an
std::variant<std::monostate, Checking, Savings> a;
And then define an implement a >>
for this, which will replace the default-constructed a
monostate with an instance of one or the other class.
Note that the type of the object a
is still fixed, and no rules are broken: a
is a variant type. It has a specific type that's defined at compile-time.
CodePudding user response:
If you want polymorphism you need pointers or references. Objects are always the type you declare them as. Nothing more, nothing less.
So you need a separate factory function that can decide which type to create at runtime. For example, it could look something like this:
std::unique_ptr<Account> read_account(std::istream& is)
{
std::string type = read_type(is);
if (type == "checking") {
auto acct = std::make_unique<Checking>();
is >> *acct;
return acct;
} else {
auto acct = std::make_unique<Savings>();
is >> *acct;
return acct;
}
return {}; // or throw
}