So I have a base class called items, 2 inherited classes from items called consumable and equipment, and 2 more inherited classes from each of those. Each have the function toString(), with it building up as you go down the inherited list. But here is my issu. I need to put 4 objects inherited from consumable and equipment into an array of items by pointers. How do I do that?
I have this code currently in my main:
Weapon greatSword("Great Sword", "A sword forged for mighty warriors", 12.50, true, 1, 150.00f, false, 13, "Slashing");
Armor mekiChestplate("Meki's Chest Plate", "A chest plate given to me by my mother", 1500.25f, false, 25, 2000.50f, true, "Chest", 18);
Food pie("Grandma's Pie", "Baked with love and affection", 10.35f, true, 5, 150, 0);
Potion spiderVenom("Spider's Venom", "Poision picked up from a spider", 100.55f, false, 10, 100, 1);
Item inventory[4]
{
greatSword,
mekiChestplate,
pie,
spiderVenom
};
for(int i = 0; i < 4; i++)
{
cout << inventory[i].toString() << endl;
cout << "-----------------------------------------------------------" << endl;
}
return 0;
This works minus that they don't call their own toString, just the Item toString. How can I put the 4 items into an array of pointers?
As mentioned in comments above; the array should be an Item* type. Since question is posted as C++14, using <array> allows you to access the values by reference; instead of manually indexing. This is more scalable as the for loop doesn't have to be updated in the future. It also eliminates possible bugs or errors when the array size doesn't match the 'for' loop.
In order to access the child class function using the base class pointer, a virtual function needs to be defined. The example below demonstrates how to implement the virtual function in each class.
For bonus points, it also demonstrates how to call the parent's toString within each child class.
#include <array>
#include <string>
#include <iostream>
class Item
{
public:
Item(const char* const name):
mName(name)
{}
virtual std::string toString() const
{
return mName;
}
private:
std::string mName;
};
class Equipment : public Item
{
public:
Equipment(const char* const name):
Item(name)
{}
virtual std::string toString() const override
{
const std::string extraInfo {"Equipment->"};
const std::string item {Item::toString()};
return extraInfo + item;
}
};
class Consumable : public Item
{
public:
Consumable(const char* const name):
Item(name)
{}
virtual std::string toString() const override
{
const std::string extraInfo {"Consumable->"};
const std::string item {Item::toString()};
return extraInfo + item;
}
};
class Weapon : public Equipment
{
public:
Weapon(const char* const name):
Equipment(name)
{}
virtual std::string toString() const override
{
const std::string extraInfo {"Weapon->"};
const std::string item {Equipment::toString()};
return extraInfo + item;
}
};
int main()
{
Weapon greatSword("Great Sword");
Weapon mekiChestplate("Meki's Chest Plate");
Consumable pie("Grandma's Pie");
Consumable spiderVenom("Spider's Venom");
std::array<Item*, 4> inventory
{
&greatSword,
&mekiChestplate,
&pie,
&spiderVenom
};
for (auto it : inventory)
{
std::cout << it->toString() << std::endl;
std::cout << "-----------------------------------------------------------" << std::endl;
}
return 0;
}
Related
Im new to C++ and I am curious to know if you can create multiple constructors with the same arguments. Say for example I have this class in which I have patients and I have their name and their age. I know I can create a constructor like this:
class hospital {
hospital(){
setname("John");
setage(24);
}
private:
string name;
int age;
};
but could I create another constructor just like I did above. Something like:
hospital patientBilly(){
setname("Billy");
setage(32);
}
The problem is that you redefine the constructor. Allowed is only one definition.
Simplified example:
void myFunc (){};
void myFunc (){};
int
main ()
{
myFunc ();
}
I whould make the Hospital class like this:
#include <string>
struct Hospital // struct here to signal we have no invariant. you could also use a class and make the member public
{
std::string name{}; // no setter and getter if you do not have invariant.
int age{};
};
int
main ()
{
auto hospital = Hospital{ .name = "John", .age = 42 }; //c++20 Designated Initializers so we can construct Hospital with a name and age without defining a constructor
}
I believe you are currently only a bit confused. So lets become the things sorted...
A class describes how objects should behave. The constructor is part of that description and equal to all the instances it will later on create. Your first step for understanding should be: There is a single class and multiple instances/objects of it.
So you write a single class and give for each of the instances/objects different parameters to get different objects.
Example:
class hospital {
public:
hospital(const std::string& name_, int age_ ):
name { name_ }, age{ age_ }{
}
void Print() const
{
std::cout << "Hospital" << name << ":" << age << std::endl;
}
private:
std::string name;
int age;
};
int main()
{
hospital hospital1{ "John", 24 };
hospital hospital2{ "Bill", 77 };
hospital1.Print();
hospital2.Print();
}
You can also create a different class for every of your later created objects, but I believe that is never what you want to do, especially not at the beginning of your C++ career!
If you want to create some kind of list of instances, you can store the objects in containers and act on the containers as you like.
int main()
{
std::vector< hospital > objs;
objs.emplace_back( "John", 24 );
objs.emplace_back( "Bill", 77 );
for ( const auto& hos: objs )
{
hos.Print();
}
}
In your problem you have two concepts, which you are trying to mix.
hospitals and patients. So it makes sense to model them as two distinct classes.
This way you can model a patient as something that has an age and a name.
And a hospital as something that "contains" patients.
Give the patient a contructor where you can pass age and name.
And give the hospital a method or methods to add patients.
In the example I show to variants of how you could add patients to a hospital.
I also have use unsigned variable types for numbers that can never be smaller then 0. And I use the const keyword a lot for places in the code where values must only be used, and should not be changed.
#include <iostream>
#include <string>
#include <utility>
#include <vector>
//---------------------------------------------------------------------------------------------------------------------
class patient_t
{
public:
// You need a constructor like this
patient_t(const unsigned int age, const std::string& name ) :
m_age{ age },
m_name{ name }
{
}
// getter function for observing private data
const unsigned int& age() const noexcept
{
return m_age;
}
// getter function for observing private data
const std::string& name() const noexcept
{
return m_name;
}
private:
unsigned int m_age;
std::string m_name;
};
// a useful output function to have (will make code later shorter)
std::ostream& operator<<(std::ostream& os, const patient_t& patient)
{
os << "Patient : " << patient.name() << ", age : " << patient.age() << std::endl;
return os;
}
//---------------------------------------------------------------------------------------------------------------------
class hospital_t
{
public:
void add_patient(const unsigned int age, const std::string& name)
{
m_patients.emplace_back(age,name); // will call patient constructor with two parameters age and name and puts it into vector
}
void add_patient(const patient_t& patient)
{
m_patients.push_back(patient); // store a copy of patient in the vector
}
const auto& patients() const
{
return m_patients;
}
private:
std::vector<patient_t> m_patients;
};
//---------------------------------------------------------------------------------------------------------------------
int main()
{
hospital_t hospital;
patient_t billy{ 42, "Billy" };
hospital.add_patient(billy);
hospital.add_patient(31, "Jane");
for (const auto& patient : hospital.patients())
{
std::cout << patient;
}
}
If I have understood correctly then what you need is to define two constructors
hospital( const std::string &name, int age )
{
setname( name );
setage( age );
}
hospital() : hospital( "John", 24 )
{
}
Then you will can write declaring an object of the class
hospital patientBilly( "Billy", 32 );
i am facing issue which i want to create abstract class and 4 subclasses. Abstract class = Entry , and other subclasses are given in the code down.
class entry {
friend ostream &operator<<(ostream &os, const entry &obj);
private:
static constexpr char *def_info = "Undefind";
protected:
string desc;
int ID;
static int counter;
public:
entry() : entry(def_info) {}
entry(string input_s);
void setDesc(string);
string getDesc() const;
int getID() const;
virtual string getContents() const = 0;
virtual void displaying(ostream &os) const = 0;
virtual ~entry() = default;
};
int entry::counter = 0;
entry::entry(string input_s) :
desc{input_s} {
++counter;
ID = counter;
}
ostream &operator<<(ostream &os, const entry &obj) {
os << obj.getContents()<<endl;
obj.displaying(os);
return os;
}
void entry::setDesc(string input) {
desc = input;
}
string entry::getDesc() const {
return desc;
}
int entry::getID() const {
return ID;
}
//PhoneEntry extending the Entry with a phone number
class phone_entry :virtual public entry {
private:
static constexpr char *text = "Undefind";
static constexpr int def_no = 48000000000;
protected:
int phone_number;
public:
phone_entry(string input_s = text, int input = def_no) :
entry(input_s), phone_number(input) {}
virtual string getContents() const override {
ostringstream output;
output << "ID: " << ID << "\nD: " << desc << "\nPhone number : " << phone_number;
return output.str();
}
virtual ~phone_entry() = default;
};
//EmailEntry extending the Entry with an e-mail addres
class email_entry : virtual public entry {
private:
static constexpr char *def_info = "Undefind";
protected:
string email;
public:
email_entry(string des = def_info, string email_entry = def_info) :
entry(des), email{email_entry} {}
virtual string getContents() const override {
ostringstream output;
output << "ID: " << ID << "\nD: " << desc << "\nEmail : " << email;
return output.str();
}
virtual ~email_entry() = default;
};
//AddressEntry extending the Entry with an address containing a city, a street and a house number
class address_entry : virtual public entry {
private:
static constexpr char *def_info = "Undefind";
static constexpr int def_no = 0;
protected:
string city;
string street;
int house_number;
public:
address_entry(string des = def_info, string c = def_info, string s = def_info, int hn = def_no) :
entry{des}, city{c}, street{s}, house_number{hn} {}
virtual string getContents() const override {
ostringstream output;
output << "ID: " << ID << "\nD: " << desc << "\nCity: " << city << "\nStreet: " << street << "\nHouse number: "
<< house_number;
return output.str();
}
virtual ~address_entry() = default;
};
class contact_book : virtual public entry {
static constexpr char *def_info = "Undefind";
private:
map<string,entry *> contacts;
string nick_name;
public:
class error_mesg : public logic_error {
public:
error_mesg(const string message = "NULL") :
logic_error(message) {}
};
contact_book(string e = "undefind") :
entry{def_info},nick_name{e} {}
void add(string a , entry &content){
contacts.insert(make_pair(a,&content));
}
virtual void displaying(ostream &os) const override {
os << "TESTING";
}
};
I want to use contact_book class and use map container to insert the key and values to any of the subclasses like ("cool", new phone_entry("NAME",000000) by using add method that it has two parameters one for the key and other it must have connection to the other classes so i thought that using entry obj will do the job ofc i used pointer in the member because i want to use Polymorphism. also i dont have any idea how i can use the getContencts and it knows from which subclass calling. For example , he asked that the main will look like this :
ContactBook contacts(“My contacts”);
contacts.add(“Johny”, new PhoneEntry(“John Smith”, 100200300));
contacts.add(“Lisa”, new EmailEntry(“Lisa Wood”, “lisa#gmail.com”));
contacts.add(“Andy”, new AddressEntry(“Andrew Fox”, “Warsaw”, “Green St.”, 7));
cout << contacts;
//result (ordered):
//Andrew Fox: Warsaw, Green St. 7 (pos. 3)
//John Smith: phone 100200300 (pos. 1)
//Lisa Wood: e-mail lisa#gmail.com (pos. 2)
try {
cout << contacts[“Andy”].getContents() << endl;
//result:
//Andrew Fox: Warsaw, Green St. 7 (pos. 3)
can you please help me out how to implement them and get what he wants and how & will work on that adding method and new as well in main func.
You are not pretty clear about what your actual problem is – so I'll assume you have trouble getting the desired output for the entire contact book...
First, some other issues, though:
It is meaningless to let contact_book inherit from entry - the book contains entries, it is not one. It seems as if you only inherited to be able to override displaying function to be able to use the already defined operator<< for entry class. But that's a bad reason for inheriting. Instead, you should provide a separate overload of operator<< for your contact book:
std::ostream& operator(std::ostream& s, contact_book const& cb); // coming to later
Then get used to reuse code where appropriate; I assume getContents should output the same string that would be written to std::cout via operator<<. OK, then let's profit from:
std::string entry::getContents()
{
std::ostringstream s;
s << *this;
return s.str();
}
You don't need to have it virtual any more (and shouldn't).
I personally would go with a default for displaying function (that's not a very good name, though, you should prefer imperative forms 'display', perhaps even better: 'printToStream' or just 'printTo'):
void entry::printTo(std::ostream& s)
{
// output members to s
}
Then your inheriting classes could re-use it:
void phone_entry::printTo(std::ostream& s)
{
entry::printTo(s); // use parent's version first to print common data
// now append phone number to s...
}
Users should rather use operator<< instead of printTo function, though. Might be a good idea to have it protected (or even private).
Finally getting back to outputting the contact book:
std::ostream& operator(std::ostream& s, contact_book const& cb)
{
// you want to output every entry? then do so:
for(auto& e : cb.contacts)
{
s << *e.second << std::endl;
// ^^^^^^^ map entries are of type std::pair<key_type const, mapped_type>
// ^ you stored pointers, operator<< accepts reference
}
}
Again, you'd be re-using code already written.
One last note: You are mixing classic initialisation (parentheses) and uniform initialisation (braces), one time even in one single line (email_contact):
entry(des), email{email_entry}
I personally think UI in general has some valid reasoning, the way it was implemented in C++ is broken, though. There are quite a few other issues with, my 'favourite' one is:
std::vector<int> v0{7}; // gives you a vector with 7 elements, all 0!!!
// with classic initialization:
std::vector<int> v1(7); // now clear, you WANT such a vector!
std::vector<int> v2({7}); // now clear, you want initializer list
You now can follow my reasoning or not (others opt for UI nonetheless to profit from the advantages of), but whatever you decide – please do it consistently over the entire file/project!
Lets say I have two classes car and service. Is it possible to create the elements for both vector objects(note: I don't know if is actually refereed to as vector objects), of the car and service classes. Once both elements are created I would only like the car class constructor to be called later to have the service constructor called to get the user information?
Also if it is possible is it possible without having to change the Service constructor to a method?
using namespace std; // I know this is not the best, prof wants us to use it
class Car { Car() { //Get data from user } };
class Service { Service(){ //Get data from user } };
int main () {
int num;
vector<Car> car;
vector<Service> service;
car.push_back(Car{});
service.push_back();
for (int i = 0; i < car.size(); i++)
car[i].display(i);
cout << endl << car.size() + 1 << ". exit";
cin >> num;
service[num].Service::Service();
}
I would recommend using a std::map instead of std::vector which choice naturally follows from your task. By using it, you will be storing valid Service elements only.
map<int,Service> service;
car.push_back(Car{});
for (int i = 0; i < car.size(); i++)
car[i].display(i);
cout << endl << car.size() + 1 << ". exit";
cin >> num;
service[num]; //Service constructor will be called
I'm thinking you are looking for something like this:
class Car {
private:
std::string _make;
std::string _model;
std::string _vinNumber;
std::size_t _year;
public:
Car() : _year( 0 ) {} // default
Car( const std::string& make, const std::string& model,
const std::string& vinNumber, const std::size_t& year ) :
_make( make ), _model( model ),
_vinNumber( vinNumber ), _year( year ) {
}
void setCarInfo( const std::string& make, const std::string& model,
const std::string& vinNumber, const std::size_t& year ) {
_make = make;
_model = model;
_vinNumber = vinNumber;
_year = year;
}
std::string makeOf() const { return _make; }
std::string modelOf() const { return _model; }
std::string vinNumberOf() const { return _vinNumber; }
std::size_t yearOf() const { return _year; }
};
class Service {
private:
std::string _dealership;
std::size_t _currentMiles;
public:
Serivce() {}
std::string dealershipOf() const { return _dealership; }
std:size_t currentMilesOf() const { return _currentMiles; }
void setOrChangeDealership( const std::string& dealership ) {
_dealership = dealership;
}
void setOrChangeCurrentMiles( std::size_t miles ) {
_currentMiles = miles;
}
void setOrChangeCurrentMiles( const std::size_t& miles ) {
_currentMiles = miles;
}
};
int main() {
std::vector<Car> cars;
std::vector<Service> services;
// you can add Car to vector by either default constructor
// to be filled out later or by user defined constructor
cars.push_back( Car( "Honda", "Civic", "75273250323XMD252AG9", 2017 ) );
// or
cars.push_back( Car() );
// then you can at some point in time update elements in container
cars[i].setCarInfo( "Dodge", "Charger", "9259356M325D2680A217B", 2015 );
// As with the service class there is only a "default" constructor
services.push_back( Service() );
// Service's members will have to be updated manually and later.
return 0;
}
Regardless of what container you use, or even if you have a single instance of a class object; a CTOR for that class will be called. The only way that one will not is if either A: you declare it as protected or private in the class the prevents the class from being declared which is used with inheritance and polymorphism, or if you declare the constructor as a deleted function: SomeClass() = delete. There is no possible way to have a class instance without its constructor being called either implicitly by the compiler or explicitly by you.
Even something as simple as this:
class A {
public:
int x;
};
int main() {
A a;
a.x = 5;
return 0;
}
The line A a; behind the scenes the compiler will invoke A() on a so it would actually look like this:
A a();
Using its default constructor.
Since C++11, you have the list-initialization for vector and other containers.
http://en.cppreference.com/w/cpp/language/list_initialization
Which means, you can put an enumeration of elements in a vector while initialization.
You can use your own class constructor in it:
std::vector<Car> cars {Car(...), Car(...), Car(...)}; //C++11
Since I can't comment your question yet, is it what you expected?
I want to compare the object type of a child class which inherits from a parent class and is stored in a vector of parent class as below:
#include <string>
#include <iostream>
#include <vector>
#include <typeinfo>
using namespace std;
class Agent{
public:
Agent(string nam){ name = nam; }
~Agent();
protected:
string name;
};
class Human :public Agent{
public:
Human(string nam, int a):Agent(nam){ age = a; }
~Human();
protected:
int age;
};
int main(){
vector<Agent*> agents;
Agent* agent=new Agent("ask");
Human* human=new Human("ask2",18);
Agent* agent2=new Human("AgentAsk",20);
agents.push_back(agent);
agents.push_back(human);
agents.push_back(agent2);
cout << (typeid(agents[1]) == typeid(Agent*)) << endl; /// True
cout << (typeid(agents[1]) == typeid(Human*)) << endl; /// I expect it to be true but its false
cout << (typeid(agents[1]) != typeid(Agent*)) << endl; /// False
return 0;
}
I need help to obtain the proper result.
I searched for it but could not find a proper solution and explanation.
Please, try to explain your code as much as possible.
You can use type traits for your classes, but if you need a simple (quick and dirty, maybe) solution, you may do it as follows:
#include <string>
#include <iostream>
#include <vector>
#include <typeinfo>
using namespace std;
class Agent{
public:
static const string TYPE;
explicit Agent(const string& nam) : name(nam) {}
virtual ~Agent(){}
virtual string type() const {
return TYPE;
}
protected:
string name;
};
const string Agent::TYPE = "Agent";
class Human :public Agent {
public:
static const string TYPE;
Human(const string& nam, int a):Agent(nam), age(a) {}
~Human(){}
virtual string type() const {
return TYPE;
}
protected:
int age;
};
const string Human::TYPE = "Human";
int main(){
vector<Agent*> agents;
Agent* agent=new Agent("ask");
Human* human=new Human("ask2",18);
Agent* agent2=new Human("AgentAsk",20);
agents.push_back(agent);
agents.push_back(human);
agents.push_back(agent2);
for(auto agent : agents) {
cout << agent->type() << " ";
cout << boolalpha << (agent->type() == Agent::TYPE) << endl;
}
//free up memory allocated using new
// or just use smart pointers
return 0;
}
It's better to define an abstract class and move the abstraction (like type() method) up and other details down to the derived classes.
Here is a possible approach to differentiate the types in a hierarchy at runtime (comments in the code, as requested by the OP):
#include<vector>
#include<cassert>
// This is a simple class that acts as a counter
struct Cnt {
static int cnt;
};
int Cnt::cnt = 0;
// A template class helps us to differentiate
// the types and to give them a set of values
// that identify the actual types at runtime
template<typename T>
struct Type: private Cnt {
static const int type;
};
template<typename T>
const int Type<T>::type = Cnt::cnt++;
// The Agent offers a virtual method that
// returns a numeric identifier of the type.
// The above mentioned classes are used
// to generate an unique value for this type.
class Agent {
public:
virtual int type() const {
return Type<Agent>::type;
}
};
// If you want Human to have its own
// numeric identifier, you can simply override
// the inherited method and return a different
// type.
// Using the Type class is still the right
// solution. It assures that the returned type
// won't collide with the ones generated so
// far.
class Human: public Agent {
public:
int type() const override {
return Type<Human>::type;
}
};
int main() {
std::vector<Agent*> vec;
vec.push_back(new Agent);
vec.push_back(new Human);
assert(vec[0]->type() == Type<Agent>::type);
assert(vec[0]->type() != Type<Human>::type);
assert(vec[1]->type() == Type<Human>::type);
assert(vec[1]->type() != Type<Agent>::type);
}
It's pretty invasive, but this way you can also decide not to give a different type to a child if you want.
A note on typeid.
From here you can find that:
There is no guarantee that the same std::type_info instance will be referred to by all evaluations of the typeid expression on the same type
You wouldn't have had guarantees even if working with different types. Anyway, you are using the typeof operator each time on the same type.
You created a vector of Agent*, so (typeid(agents[1]) == typeid(Human*)) is false because agents[1] is an Agent, not a Human.
Im learning C++, and I am trying to do a little app. My app takes an informal ticket (without TAX) like this:
2
3 Mi_primera_tablet 7.95
1 El_general_en_su_laberinto Gabriel_García_Márquez 23.50
Where the first line is the number of items
In the second and third line= type of tax + title + price without TAX
The items can be of different types: books(TAX type 3), toys(TAX type 1)
All types inherit from the class article, but depending of the TAX type the price will be different (polymorphism).
I need to store all items (different types) in an array, how can I do it?
You can store pointers in the array.
Exapmle (c++11):
#include <iostream>
#include <vector>
#include <memory>
struct A {
int value;
};
struct B {
double item;
};
class Element {
public:
explicit Element(A a);
explicit Element(B b);
const A * AsA() const;
const B * AsB() const;
private:
class AbstractElement {
public:
virtual ~AbstractElement() {
}
protected:
AbstractElement() {
}
};
template <typename T>
struct ConcreteElement : public AbstractElement {
T body;
explicit ConcreteElement(T input_body)
: body(std::move(input_body)) {
}
};
std::unique_ptr<AbstractElement> element_;
};
Element::Element(A a)
: element_(new ConcreteElement<A>(a)) {
}
Element::Element(B b)
: element_(new ConcreteElement<B>(b)) {
}
const A * Element::AsA() const {
const auto concrete_element =
dynamic_cast<ConcreteElement<A> *>(element_.get());
return concrete_element ? &(concrete_element->body) : nullptr;
}
const B * Element::AsB() const {
const auto concrete_element =
dynamic_cast<ConcreteElement<B> *>(element_.get());
return concrete_element ? &(concrete_element->body) : nullptr;
}
int main() {
std::vector<Element> values;
values.push_back(Element(A{1}));
values.push_back(Element(B{1.5}));
values.push_back(Element(A{-5}));
values.push_back(Element(B{0}));
for (const auto & element : values) {
const auto p_a = element.AsA();
if (p_a) {
std::cout << "A: " << p_a->value << std::endl;
} else {
const auto p_b = element.AsB();
std::cout << "B: " << p_b->item << std::endl;
}
}
return 0;
}
output:
A: 1
B: 1.5
A: -5
B: 0
Maybe you can try boost::variant library, it act as a wrapper around anything. then you can store many boost::variant wrapper in an array
if I understood your question correctly, you need to know how to define an array of your base class with it's derived classes. If this is the case, you can do it by defining an array in the base class, which in your case would look something like this:
article ArrayName [n];
Books Books = new Books();
//do some thing with the books object
ArrayName[0] = Books;
All types inherit from the class article, but depending of the TAX
type the price will be different (polymorphism).
type or TAX type could be stored as a member in Class article.
No polymorphism is needed here.
The items can be of different types: books(TAX type 3), toys(TAX type
1)
Or you could store only the type (books, toys), and do a lookup in a table type | TAX-type, if the TAX types will always be the same for the full range of each type.
But if you really have or need a derived class for each type (for example to store different properties), you could call a virtual function in the derived classes CalcTax() for example.
An array with (baseclass*) pointers to the items could be created, and you can loop through that array, and call CalcTax() on each item, which will call the correct virtual function.
For example:
#include <iostream>
class Base
{
public:
virtual CalcTax() = 0;
};
class Type_1 : public Base
{
public:
virtual CalcTax() {std::cout << "Type_1\n";}
};
class Type_2
{
public:
virtual CalcTax() {std::cout << "Type_2\n";}
};
int main()
{
Base *arrItems[2]; // or better use std::vector<> etc.
Type_1 t1; // just a quick demo of polymorphism
Type_2 t2;
arrItems[0] = (Base*)&t1;
arrItems[1] = (Base*)&t2;
for (int i = 0; i < 2; ++i) {
arrItems[i]->CalcTax();
}
return 0;
}