Search code examples
c++classpointersvectorpolymorphism

How do I create a derived pointer class variable?


Currently doing a homework assignment and I am supposed to create a vector that hold different types of cards. So I created a card class and 2 derived classes (ID card, bank card). Each class has their distinctive info (name, etc). I do not know how to create id and bank cards in the vector. In addition, can someone explain polymorphism and how is it used in this code? I tried using & but I am not sure what is the exact use of that symbol.

std::cout << "Card Type: " ;
std::cin >> card_type;

while (card_type)
{
    if (card_type == 1)
    {
        std::cout << "Institution name: ";
        getline (std::cin, institute_name);
        std::cin.ignore();
        std::cout << "Cardholder name: ";
        getline (std::cin, card_name);
        std::cin.ignore();
        std::cout << "Expiration date mmddyyyy (0 if none): ";
        std::cin >> expire_date;
        std::cout << std::endl <<std::endl;
        Card* regular = new Card(institute_name, card_name, expire_date);
        cardbook.push_back (regular);
    }
    else if (card_type == 2)
    {
        std::cout << "Institution name: ";
        getline (std::cin, institute_name);
        std::cin.ignore();
        std::cout << "Cardholder name: ";
        getline (std::cin, card_name);
        std::cin.ignore();
        std::cout << "Expiration date mmddyyyy (0 if none): ";
        std::cin >> expire_date;
        std::cout << "ID number: ";
        std::cin >> identify_num;
        std::cout << "DOB mmddyyyy (0 if not listed)";
        std::cin >> birthdate;
        std::cout << std::endl << std::endl;
        IDCard* identification = new IDCard(institute_name, card_name, expire_date, identify_num, birthdate);
        cardbook.push_back (identification);
    }
    else if (card_type == 3)
    {
        std::cout << "Institution name: ";
        getline (std::cin, institute_name);
        std::cin.ignore();
        std::cout << "Cardholder name: ";
        getline (std::cin, card_name);
        std::cin.ignore();
        std::cout << "Expiration date mmddyyyy (0 if none): ";
        std::cin >> expire_date;
        std::cout << "Account number: ";
        std::cin >> account_num;
        std::cout << "Card Security Code: ";
        std::cin >> secure_code;
        std::cout << std::endl << std::endl;
        BankCard* bank = new BankCard (institute_name, card_name, expire_date, account_num, secure_code);
        cardbook.push_back (bank);
    }

Solution

  • create a vector that hold different types

    You can do this by creating a class hierarchy and storing pointers to the base type in the vector. It sounds like you've created the hierarchy but you haven't shown your code and I cannot comment further on your specific issue.

    Example

    // This example creates a base type with 2 derived types and stores the
    // derived types in a `vector` using a base type pointer.
    //
    // The polymorphism is observed when `Base::action` is called but
    // `action` from the "real" type `Foo` and `Bar` is invoked.
    
    #include <iostream>
    #include <memory>
    #include <vector>
     
    class Base
    {
    public:
        virtual ~Base() {}
        virtual void action() const = 0;
    };
     
    class Foo : public Base
    {
    public:
        void action() const override { std::cout << "Foo::action\n"; }
    };
     
    class Bar : public Base
    {
    public:
        void action() const override { std::cout << "Bar::action\n"; }
    };
     
    int main()
    {
        // A `vector` of base type pointers
        std::vector<std::unique_ptr<Base>> values;
    
        // Add a `Foo` type to the `vector`
        values.emplace_back(new Foo());
    
        // Add a `Bar` type to the `vector`
        values.emplace_back(new Bar());
     
        // For each `v` (which is a `Base` pointer) in `values`
        for(auto& v : values)
        {
            // Calling `action` through the `Base` pointer
            v->action();
        }
     
        return 0;
    }
    

    Output

    Foo::action
    Bar::action