How to overload << operator in derived classes on c++ [duplicate] - c++11

This question already has answers here:
Making operator<< virtual?
(3 answers)
Closed 2 months ago.
In my example, I have two classes: Parent and Child. I'm using a vector of pointers to Parent (vector<Parent*> v;) and I'm inserting objects of both classes into v. I'm trying to print the classes attributes overloading the operator <<. My code prints the Parents attributes (name and age) and I would like to know how to print the derived attributes from Parent and the Child's own attribute.
class Parent{
friend ostream &operator<<(ostream &saida, Parent &parent){
out << "Name: " << parent.name << ", Age: " << parent.age << "." << endl;
return out;
}
public:
Parent(string name, int age){
this->name = name;
this->age = age;
}
string& getName(){
return name;
}
int& getAge(){
return age;
}
private:
string name;
int age;
};
class Child: public Parent{
friend ostream &operator<<(ostream &out, Child &child){
out << "Name: " << child.name << ", Age: " << child.age << ", School: " << child.school << "." << endl;
return out;
} // <- DonĀ“t know what to do here
public:
Child(string name, int age, string school): Parent(name, age){
this->school = school;
}
string& getType(){
return type;
}
private:
string school;
};
int main(){
vector<Father*> v;
v.push_back(new Parent("Father", 30));
v.push_back(new Child("Child", 10, "School"));
for(int i = 0; i < v.size(); i++){
cout << *v[i];
}
return 0;
}
It prints:
Name: Father, Age: 30
Name: Child, Age: 10

In Parent:
friend std::ostream &operator<<(std::ostream& out, Parent const& parent){
parent.print(out);
out << ".\n";
return out;
}
virtual void print(std::ostream& out) const {
out << "Name: " << name << ", Age: " << age;
}
in Child:
void print(std::ostream& out) const override {
Parent::print(out);
out << ", School: " << school;
}
and things should work the way you want.
To use C++'s object inheritance system and get dynamic dispatch, you need to use virtual dispatch. Here, I forward the operator<< to a virtual print method.
This print method doesn't include the ".\n" on purpose; that allows children to add new fields easily.
The Child class does not have a operator<<, but uses the Parent's operator<<.

Related

Overloading output operator is not working as intended

I'm trying to overload << to print the protected members of a class as a string, but when I try to use it in another class doing std::cout << player2; I get "0x7f60b0100" as output.
"player2" is an Actor*, so I'm not sure what's happening.
class Actor {
private:
string type;
protected:
int health;
int damage;
vector<MoveType> moves;
public:
Actor(string type, int health): type{ type }, health{ health }{damage=0;}
virtual void Hit(int damage){health = health-damage;}
virtual void Heal(int amount){health=+amount;}
const vector<MoveType>& GetMoves() const {return moves;}
bool IsDead() { return health <= 0; }
friend ostream& operator<<(ostream& out, const Actor& actor){
return (out << "DAMAGE DONE: " << actor.damage << "HEALTH: "<< actor.health);
}
};
As you've said it's a pointer to an Actor instance, so that's what you get printed, the value of this pointer.
You need to derefernce the pointer:
std::cout << *player2;

In-class initialization of data members. Will the value left after the inheritance?

So simple question is, if I have such situation:
class FooA{
public:
int getID(){
return ID;
}
private:
int generateID(){
//some code that generate unique ID
}
int ID = generateID();
};
class FooB : public FooA{
};
Will the ID initialized in the FooA goes also to the FooB? So for FooB I can use getID and for example get value from FooA::generateID.
Every instance of both classes will run generateID anew, producing unique value for every instance.
No, ID generated for an instance of parent class won't be same as ID generated for an instance of descendant, because they would have different instances.
Yes, descendant can use or expose parent's methods.
class FooA{
public:
int getID(){
return ID;
}
private:
int generateID(){
static int i = 0;
return i++;
}
int ID = generateID();
};
class FooB : public FooA{
};
int main() {
// your code goes here
cout << (FooA()).getID() << endl; // 0
cout << (FooA()).getID() << endl; // 1
cout << (FooB()).getID() << endl; // 2
return 0;
}
https://ideone.com/5Klf3d

Trying to print out values from an instantiated class in C++. Getting a random value as a result

So I'm doing a lab for one of Microsoft's courses on EDX, and they wanted me to create a class constructor called, Person, and then instantiate an object using the constructor and print out the values.
The issue I'm having, is that when I try to to print out the values, I'm getting the common, "random memory", value that you get when you haven't given a variable any data, and can't figure out why I'm getting this issue. PLEASE help!
Here's the code from my main() function, instantiating and printing out the values.
Person *pPerson = new Person("Bob", "Schwimmer", 49, 57, 201);
cout << "His name is: " << pPerson->GetFirstName() << " " << pPerson->GetLastName() << endl;
cout << "He is " << pPerson->GetAge() << endl;
cout << "He weighs (in lbs) " << pPerson->GetWeight() << endl;
cout << "He is " << pPerson->GetHeight() << " feet tall." << endl;
And here's my class constructor:
class Person
{
private:
string firstName;
string lastName;
int age;
int height;
int weight;
public:
Person(string fName, string lName, int age, int height, int weight)
{
fName = firstName;
lName = lastName;
age = age;
height = height;
weight = weight;
}
~Person()
{
cout << "Deconstructor has been called" << endl;
}
string GetFirstName() { return this->firstName; };
string GetLastName() { return this->lastName; };
int GetAge() { return this->age; };
int GetHeight() { return this->height; };
int GetWeight() { return this->weight; };
void SetFirstName(string fName) { fName = this->firstName; };
};
The order in your constructor is not correct: fName = firstName; should have been firstName = fName; and so on...

C++ Move constructor for class containing vector

I have written a move constructor for a class in the following way:
class A
{
std::vector<double> m;
A(A&& other)
: m{other.m}
{
}
}
Is this the correct way to move other.m to m?
Should I be doing this instead?
A(A&& other)
: m{std::move(other.m)}
{
}
Or perhaps I should be doing something else entirely?
The second snippet is the correct way to move other.m since it's a lvalue that needs to be turned into r-value-reference for std::vector move constructor to kick in.
even though, in this very specific example, it will be enough to simply write
A(A&& rhs) = default;
the compiler will generate a constructor that moves each member of rhs to the corresponing member of *this.
p.s. you also probably meant to make the constructor public.
/******************************************************************************
Below program demonstrates how to use move constructor and move assignment operator
*******************************************************************************/
#include <iostream>
#include <algorithm>
#include <vector>
class MemoryBlock
{
public:
MemoryBlock()
{
this->id++;
std::cout << "Default Constructor"<<std::endl;
}
// Simple constructor that initializes the resource.
explicit MemoryBlock(size_t length)
: _length(length)
, _data(new int[length])
{
this->id++;
std::cout << "Constructor In MemoryBlock(size_t). length = and id ="
<< _length << "." <<id<< std::endl;
}
// Destructor.
~MemoryBlock()
{
this->id--;
std::cout << "Destructor In ~MemoryBlock(). length = and id ="
<< _length << "."<<id;
if (_data != nullptr)
{
std::cout << " Deleting resource.";
// Delete the resource.
delete[] _data;
}
std::cout << std::endl;
}
// Copy constructor.
MemoryBlock(const MemoryBlock& other)
: _length(other._length)
, _data(new int[other._length])
{
this->id++;
std::cout << " Copy Constructor MemoryBlock(const MemoryBlock&). length = and id ="
<< other._length << "." <<id<<"Copying resource." << std::endl;
std::copy(other._data, other._data + _length, _data);
}
// Copy assignment operator.
MemoryBlock& operator=(const MemoryBlock& other)
{
std::cout << "Assignment operator In operator=(const MemoryBlock&). length = "
<< other._length << ". Copying resource." << std::endl;
if (this != &other)
{
// Free the existing resource.
delete[] _data;
_length = other._length;
_data = new int[_length];
std::copy(other._data, other._data + _length, _data);
}
return *this;
}
// Retrieves the length of the data resource.
size_t Length() const
{
return _length;
}
//Move copy constructor
MemoryBlock(MemoryBlock&& other) noexcept
: _data(nullptr)
, _length(0)
{
std::cout << "Move Constructor In MemoryBlock(MemoryBlock&&). length = "
<< other._length << ". Moving resource." << std::endl;
// Copy the data pointer and its length from the
// source object.
_data = other._data;
_length = other._length;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other._data = nullptr;
other._length = 0;
}
// Move assignment operator.
MemoryBlock& operator=(MemoryBlock&& other) noexcept
{
std::cout << "Move assignment operator In operator=(MemoryBlock&&). length = "
<< other._length << "." << std::endl;
if (this != &other)
{
// Free the existing resource.
delete[] _data;
// Copy the data pointer and its length from the
// source object.
_data = other._data;
_length = other._length;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other._data = nullptr;
other._length = 0;
}
return *this;
}
private:
size_t _length; // The length of the resource.
int* _data; // The resource.
static int id;
};
int MemoryBlock::id=0;
int main()
{
std::vector<MemoryBlock> v1;
MemoryBlock m1(100);
MemoryBlock m2(100);
MemoryBlock m3(100);
v1.push_back(m1);
v1.push_back(m2);
v1.push_back(m3);
return 0;
}

Not able to store data in a private member variable from a const member function - FIX8 c++

This is my header :
class my_router_client : public FIX8::my::mine_Router {
private:
mine_session_client& _session;
mutable std::vector<std::string> vSymbolList;
public:
my_router_client(mine_session_client& session) : _session(session) {}
virtual bool operator() (const FIX8::my::SecurityList *msg) const;
void sendToServer(FIX8::Message *);
void logout();
void itertool() const;
};
I am trying to save the data obtained from security list response to the vSymbolList vector. After handling security response I am trying to iterate through the vector by itertool method. But every time I end up with an empty vector. I tried printing the contents of the vector inside securitylist response function
virtual bool operator() (const FIX8::CX::SecurityList *msg) const;
and I am able to print the contents. Is it some kind of race condition inside threads?
this is the security list response handler
bool cx_router_client::operator() (const CX::SecurityList *msg) const
{
GroupBase *dad(msg->find_group< CX::SecurityList::NoRelatedSym >());
if (dad) {
for (size_t cnt(0); cnt < dad->size(); ++cnt) {
CX::Symbol symbol;
MessageBase *details(dad->get_element(cnt));
details->get(symbol);
string ss;
ss = symbol();
vSymbolList.push_back(ss);
// cout << "at :: :: " << vSymbolList[cnt] << endl;
}
cout << "no of symbol : " << vSymbolList.size() << endl;
hypersleep<h_seconds>(1);
}
return true;
}
This is the itertool method :
void my_router_client::itertool() const
{
cout << "symbol list vector size inside itertool:: " << vSymbolList.size() << endl;
stringstream ss;
ss << this_thread::get_id();
uint64_t id = stoull(ss.str());
cout << "Thread ID #### " << id << endl;
vector<string>::iterator it = this->vSymbolList.begin();
while (it != vSymbolList.end()) {
cout << *it << endl;
it++;
}
}
This is how I use the them in main :
int main()
{
const string conf_file("myfix_client.xml");
unique_ptr<ClientSessionBase> mc(new ClientSession<mine_session_client>(my::ctx(), conf_file, "DLD1"));
mc->start(false, next_send, next_receive, mc->session_ptr()->get_login_parameters()._davi());
hypersleep<h_seconds>(1);
my_router_client *test = new my_router_client(static_cast< mine_session_client& > (*mc->session_ptr()));
hypersleep<h_seconds>(1);
test->sendToServer(makeSecurityListRequest());
hypersleep<h_seconds>(1);
test->itertool();
while(1);
}

Resources