7

I have to implement polymorphism in my project. I have a virtual class called "Account". Then there are 4 subclasses: USD, EUR, GBP, and CHF. I need to read the current balance from a text file like this:

USD 50
CHF 80
GBP 10
EUR 90

and make a subclass depending on the currency.
Every currency should have its own object. Later in the program, I will implement currency exchange, exchange rates will be read from the file. I don't have any idea of how to start with these classes. What should I learn?

My code so far:

class Account{
    std::string currency;
public:
    virtual void balance() = 0;
};

class currencyAcc: public Konto {
    std::string currency;
    float balance;
    walutowe(std::string currency,float balance) {
        this->currency= currency;
        this->balance= balance;
    }
    void AccBallance() {
        std::cout << balance<< std::endl;
    }
};
Arsen Khachaturyan
  • 6,472
  • 4
  • 32
  • 36
Varkame
  • 89
  • 2
  • Not an answer, but I would suggest making `std::string currency` protected in the base class to be able to use it in the derived ones. – Jaideep Shekhar Dec 26 '19 at 10:31
  • Also, is the text file `USD 0 CHF 0 GBP 0 EUR 0` a single line only? And does each currency only exist once in the file? What I understand is that for `USD 0`, we create an object of USD with 0 balance, and likewise for each of the rest? Am I correct? – Jaideep Shekhar Dec 26 '19 at 10:41
  • It is in 4 seperate lines it should read from file. Number stands for balance, It can be any number. My intention is to create an object depending what is in the text file – Varkame Dec 26 '19 at 10:53
  • Note that in [my answer](https://stackoverflow.com/a/59488616/9414470), I am just guiding your implementation of parsing the currencies from file. If you want help on the structure on classes and program, and you have tried and are getting stuck/an error, ___just show the effort and ask___! – Jaideep Shekhar Dec 26 '19 at 12:43

2 Answers2

8

What should I learn?

Well, if you have covered the basics, you sure need some practice and guidance!

You could have a global function that:

  • reads a block of text file,
  • parses and creates the correct object dynamically (based on some condition), and
  • returns a pointer to the object (cast to the base):
Account * parseOne(std::fstream& file);    // Reference to opened file

Even if you just want the code, you will still have to go through an explanation. :)
Let us see it in a general sense.

Read a line

Very simply:

std::getline(file, line);

it. You should also check if the read was successful.

Parse it

You can do this as:

std::stringstream parse_me(line);
parse_me >> some_data_1;
parse_me >> some_data_2;
...

Create your object...

Here, you need to create it on the basis of currency_type. Do:

if(currency_type == "GBP")
{
    new_currency_object = new GBP(balance);
}

for each derived class.

...and The Code:

Putting it together:

Account * parseOne(std::fstream& file)     // Reference to opened file
{
    // To read a line from the file
    std::string line;

    // If the read failed, return NULL
    if(!std::getline(file, line))
    {
        return 0;
    }
    // Read success
    // Using stringstream so that different types of data can be parsed
    std::stringstream line_buffer(line);
    // Declare variables to be parsed
    std::string currency_type;
    float balance;

    // Now parse it (note the order!)
    line_buffer >> currency_type >> balance;

    // Create a pointer to base...
    Account * new_currency_object;

    // ...and create the object based on the currency_type
    if(currency_type == "USD")
    {
        new_currency_object = new USD(balance);
    }
    ... for each currency
    // We are done, return the fruits of our labour
    return new_currency_object;
}

(Note that I assume you have a USD(float balance) constructor. If not, set balance yourself)
to be used as:

// open the file
std::fstream currency_file("my_currencies.txt");
// Read a currency
Account * a_currency;
// When the read finishes, we get NULL
while(a_currency = parseOne(currency_file))
{
    // do something with a_currency. Maybe:
    // list_of_currencies.push_back(a_currency) it?
}

Edit: And be sure to deallocate the memory once done! In fact, use of new and raw pointers are not encouraged anymore. Thanks to this comment for suggesting it.
For further reading, see How to implement the factory method pattern in C++ correctly .
Good luck!

Jaideep Shekhar
  • 609
  • 2
  • 6
  • 17
  • 2
    @Klaus: Thank you. I apologyze. I learned from the above answer. I will from now on use raw pointers for owned memory instead of ````std::unique_ptr````. Also I will restart to use ````new```` in C++. I will refactor answers that I gave in regards to factories (like this: https://stackoverflow.com/questions/59015776/difference-in-structure-of-abstract-factory/59016040#59016040) in order to implement the above ideas. I know now that there are better solutions. I think that from the architecture point of view, it is a good idea to derive currency from account. This comment will be deleted soon – Armin Montigny Dec 26 '19 at 14:45
  • @ArminMontigny Well, everyone thinks differently. In that case, _post a better answer_! I am sure it will be upvoted (I will do so myself if it is good) and the OP can accept it as the best answer. I will also learn from it. :-) As for the structure of the program, I refrained from commenting on it myself. Maybe you can also add that part in? – Jaideep Shekhar Dec 26 '19 at 14:49
0

You need a Currency class that accepts the currency code in the constructor. The object of the Currency class can be part of the account via composition, instead of the current currency with datatype string.

alok
  • 1,068
  • 1
  • 10
  • 24
  • 1
    The main problem I have is to make 4 subclasses from text file ``` class USD: public Konto ``` ``` class EUR: public Konto ``` ``` class CHF: public Konto ``` ``` class GBP: public Konto ``` – Varkame Dec 26 '19 at 10:08
  • Is this homework, or for a real world application? In a real world application you would have a class for Currency or even better, a class for Amount, which accepts Currency Code as well as precision of the currency as attributes. Please explain what you mean by creating 4 subclasses. Do you mean, you need to inherit from an abstract base class called currency? – alok Dec 26 '19 at 10:11
  • It is homework. I am making simple wallet with 4 currencies, I have to implement currency exchange, deposit and withdraw . All currencies are supposed to be seperate classes, virtual class is Account and Currency subclass ```class USD:public Account``` is only to implement polymorphism – Varkame Dec 26 '19 at 10:20