Could somebody override this callBack()? - class

Usually, callBack() gotta be overridden in Child class.
but it doesn't. When the thread calls callBack(), it runs original method.
Is there any way to right this?
I compiled it with "g++ -o file source.cpp -lpthread"
I'm sure it is not about a compiler.
#include <iostream>
#include <unistd.h>
#include <pthread.h>
using namespace std;
class Parent
{
public:
virtual void callBack()
{
cout << "Original callBack() reported this: " << this << endl;
}
private:
pthread_t th = 0;
static void *th_func(void *arg)
{
Parent *p = (Parent*)arg;
cout << "*th_func() reported *arg: " << arg << endl;
p->callBack();
}
public:
Parent()
{
if(pthread_create(&th, NULL, th_func, (void*)this) < 0)
cerr << "thread not born." << endl;
else
cout << "thread has born." << endl;
}
~Parent()
{
if(th!=0)
pthread_join(th, NULL);
cout << "joined. Parent leaving." << endl;
}
};
class Child : public Parent
{
public:
void callBack()
{
cout << "child overridden." << endl;
}
Child() : Parent(){}
};
int main()
{
Child *ch = new Child();
delete ch;
return 0;
}

The problem with your code is that you are calling the thread function from inside the parent constructor. At that point, the Child object is not constructed yet (look up object initialisation order in C++), thus the only virtual function that it can call is the parent's.
From a C++ point of view, it's doing the right thing :).
In order to get your code to work, you have to separate the thread creation from the object creation, otherwise you'll never be able to call a function in a derived class.
Here's some more info from the C++ FAQ. And here's what Scott Meyers has to say about this topic.

Related

Segmentation Error: Help on the correct allocation memory when saving & loading binary files containing a specific structure from a class

This is my first time asking a question, so apologies if it is not done 100%:
I have a class which saves and loads a binary file with a specific data structure.
If the program creates an instance of the class, save the binary file, and creates another instance of the class to load/read the binary file consequently, everything seems 100% correct.
However, if I run the program to save the binary file and then run it again to load/read that binary file, it gives me a segmentation fault at the end.
The program still does everything it needs to do before the segmentation fault, except deconstructing the class at the end (obviously).
It looks like my allocation of the memory is not correct, but I am not sure where I am going wrong.
A simplified version of the code follow (also here: https://github.com/LenteDreyer/Tests.git )
Can someone see where I am going wrong?
class header file that save/loads the file
#ifndef __TESTS_MAP_HH__
#define __TESTS_MAP_HH__
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
typedef struct test_struct{
bool test_bool;
double test_double;
std::vector<double> test_vector;
} test_struct_t;
class map
{
private:
std::string m_path, m_str;
double m_double;
test_struct m_struct;
public:
map(const std::string& a_id);
void set_str(std::string a_str);
void set_double(double a_double);
void set_struct(test_struct a_struct);
void load_file();
void save_file() const;
void show_file() const;
~map();
};
#endif //__TESTS_MAP_HH__
class source file that save/loads the binary file
#include "map.hh"
map::map(const std::string& a_id)
{
m_path = a_id + ".bin";
m_str = "none";
m_double = 0.0;
m_struct = {false, 0.0};
}
void map::set_str(std::string a_str){
m_str = a_str;
}
void map::set_double(double a_double){
m_double = a_double;
}
void map::set_struct(test_struct a_struct){
m_struct = a_struct;
}
void map::load_file(){
std::ifstream l_inF;
l_inF.open(m_path.c_str(), std::ios::binary | std::ios::in);
l_inF.read((char*)&m_double,sizeof(double));
l_inF.read((char*)&m_struct,sizeof(test_struct_t));
size_t str_size;
l_inF.read((char*)&str_size, sizeof(str_size));
m_str.resize(str_size);
l_inF.read((char*)&m_str[0], str_size);
l_inF.close();
}
void map::save_file() const{
std::ofstream l_outF;
l_outF.open(m_path.c_str(), std::ios::binary | std::ios::out);
l_outF.write((char*)&m_double,sizeof(double));
l_outF.write((char*)&m_struct,sizeof(test_struct_t));
size_t str_size = m_str.size();
l_outF.write((char*)&str_size, sizeof(str_size));
l_outF.write((char*)&m_str[0], str_size);
l_outF.close();
}
void map::show_file() const{
std::cout << ">>-----------------------------------------------" << std::endl;
std::cout << ">> double : " << m_double << std::endl;
std::cout << ">> double : " << m_double << std::endl;
std::cout << ">> struct.bool : " << m_struct.test_bool << std::endl;
std::cout << ">> struct.double : " << m_struct.test_double << std::endl;
std::cout << ">> struct.vector : " << "size = " << m_struct.test_vector.size() << std::endl;
std::cout << ">> string : " << m_str << std::endl;
std::cout << ">>-----------------------------------------------" << std::endl;
}
map::~map(){}
main function case 1 works, and case 2 gives the segmentation fault.
#include "map.hh"
int main(int argc, char const *argv[])
{
std::string id = "mapfile";
int action = 0;
if(argc > 1) action = std::stoi(argv[1]);
else {
std::string input;
std::cout << "Enter case (1 or 2): ";
std::cin >> input;
action = std::stoi(input);
}
switch (action)
{
case 1:
{
// This works 100% (no errors and it saves/reads class perfectly)
std::vector<double> l_vect = {0.1, 0.0, 0.6};
test_struct save_struct = {true, 5.0, l_vect};
map test_save(id);
test_save.show_file();
test_save.set_double(8.0);
test_save.set_str("save this string");
test_save.set_struct(save_struct);
test_save.show_file();
test_save.save_file();
map test_load(id);
test_load.load_file();
test_load.show_file();
}
break;
case 2:
{
// gives segmentation error at the end of the program
map test_load(id);
test_load.load_file();
test_load.show_file();
}
break;
default:
break;
}
return 0;
}

C++ Parent Class with Abstracted Function that Uses Functions in a Child Class

I am trying to create a C++ parent class that has two functions, f1 and f2, to be implemented in the child class. This parent class has a function, abstractedFunction that abstracts how f1 and f2 should be used together. Both f1 and f2 are implemented in the child class as shown in the code below.
#include <iostream>
class Parent
{
public:
int f1(); // To be implemented in the derived class
void f2(int i); // To be implemented in the derived class
void abstractedFunction() { // Abstracted in the parant class
auto r = f1();
f2(r);
}
};
class Child : public Parent
{
public:
int f1() {
std::cout << "f1 is implemented in the child class\n";
return 1;
}
void f2(int i) {
std::cout << "f2 is implemented in the child class\n";
std::cout << "Return value for f1 = " << i << "\n";
}
};
int main() {
Child ch;
ch.abstractedFunction();
return 0;
}
Is such a concept implementable in C++?
Yes, You can do something like this. You need to make the functions defined in base class as pure virtual : Follow this link to know more about them and then you can create an object of derived class and assign it to the base pointer to make a required function call
#include <iostream>
using namespace std;
class Parent
{
public:
virtual int f1()=0; // To be implemented in the derived class
virtual void f2(int i)=0; // To be implemented in the derived class
void abstractedFunction() { // Abstracted in the parant class
auto r = f1();
f2(r);
}
};
class Child : public Parent
{
public:
int f1() {
std::cout << "f1 is implemented in the child class\n";
return 1;
}
void f2(int i) {
std::cout << "f2 is implemented in the child class\n";
std::cout << "Return value for f1 = " << i << "\n";
}
};
int main() {
Parent *ptr;
Child c;
ptr=&c;
ptr->abstractedFunction();
return 0;
}

Destructor trouble

I've recently read that if you use an object of a class as a reciving parameter of a function, a copy of an object has to be created automaticly. Therefore, if the destructor is included in the class, both original object and it's copy will be vanished automaticly. However, when I tried to make a small code with the same conception destructor only activated once. What can cause the problem? Thanks in advance!
#include "stdafx.h"
#include <iostream>
using namespace std;
class MyClass {
int val;
public:
MyClass(int i)
{
val = i;
cout << "Constructor is in progress" << endl;
}
void SetVal(int i)
{
val = i;
}
int GetVal()
{
return val;
}
~MyClass()
{
cout << "Destructer is in progress" << endl;
}
};
void Display(MyClass obj)
{
cout << obj.GetVal();
}
int main()
{
MyClass a(10);
cout << "Before display()" << endl;
Display(a);
cout << "After display()" << endl;
system("pause");
return 0;
}
It is called after the return statement. The first message you are seeing is from the copied object. When you get to system("pause") your original object is still in scope, so the destructor is not called. It is called after the return statement is evaluated.
Is destructor called at the end of main(); strange behavior

Singleton Implementation: counter not incrementing as expected with multiple pointers to instance

The following program aims to instantiate and use the singleton pattern class proposed by Loki Astari and accepted as answer at the following link.
C++ Singleton design pattern
Note the addition of a simple counter, by way of the private counter variable, along with the increment() mutator, and getCtr() accessor methods.
Expected program output is:
0
1
Press any key to exit...
The actual output is
0
0
Press any key to exit...
Why is the counter in the singleton class not being incremented as expected?
What follows is a minimal, complete, and verifiable program, written to illustrate the issue.
#include "stdafx.h"
#include <iostream>
#include <string>
class S {
public:
static S & getInstance() {
static S instance;
instance.counter = 0; // initialize counter to 0
return instance;
}
S(S const &) = delete;
void operator = (S const &) = delete;
void increment() { ++counter; }
int getCtr() { return counter; }
private:
S() {}
int counter;
};
int main() {
S * s; // s is a pointer to the singleton object
S * t; // t is another pointer to the singleton object.
std::cout << s->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
std::cout << "Press any key to exit...";
std::cin.get();
return 0;
}
Thx, Keith :^)
your problem is you are initializing the counter inside the
getInstance() method
instead, initialize it inside the constructor
your code should be like the following,
#include <iostream>
#include <string>
class S {
public:
static S & getInstance() {
static S instance;
// instance.counter = 0; // initialize counter to 0
return instance;
}
S(S const &) = delete;
void operator = (S const &) = delete;
void increment() { ++counter; }
int getCtr() { return counter; }
private:
S() {counter =0;}
int counter;
};
int main() {
S * s; // s is a pointer to the singleton object
S * t; // t is another pointer to the singleton object.
std::cout << s->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
std::cout << "Press any key to exit...";
std::cin.get();
return 0;
}
then the Output will be
0
1
2
3
4
5
Press any key to exit...

Virtual Functions in Class Hierarchy

I suppose it is not such a clever question but i have been spending considerable time on it and still doesnt compile
Can you please explain why?
Thanks
1>------ Build started: Project: Ch17, Configuration: Release Win32 ------
1> p731.cpp
1>\\na-13\agnolucp\my documents\visual studio 2010\projects\ch17\ch17\Bear.h(29): error C2084: function 'std::ostream &Bear::print(std::ostream &) const' already has a body
1> \\na-13\agnolucp\my documents\visual studio 2010\projects\ch17\ch17\Bear.h(19) : see previous definition of 'print'
1>p731.cpp(16): error C2264: 'Bear::print' : error in function definition or declaration; function not called
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
//Endangered
#ifndef ENDAGERED
#define ENDAGERED
#include <iostream>
class Endangered {
public:
//virtual ~Endangered();
virtual std::ostream& print(std::ostream&) const;
// virtual so needs to be defined otherwise error
virtual void highlight() const;
};
//ZooAnimal
#ifndef ZOOANIMAL
#define ZOOANIMAL
#include<string>
class ZooAnimal {
public:
ZooAnimal();
ZooAnimal(std::string animal, bool exhibit,
std::string family): Name(animal),
OnExhibition(exhibit),
FamilyName(family) { }
//virtual ~ZooAnimal();
virtual std::ostream& print(std::ostream&) const;
// accessors
std::string getName() const { return Name; }
std::string getFamilyName() const { return FamilyName; }
bool getOnExhibition() const { return OnExhibition; }
// ...
protected:
std::string Name;
bool OnExhibition;
std::string FamilyName;
// ...
private:
};
std::ostream& ZooAnimal::print(std::ostream &out) const {
return out << "I am printing ZooAnimal" << std:: endl;
}
#endif
void Endangered::highlight() const {
std::cout << "HIGHLIGHT: HEY, I AM IN DANGER" << std::endl;
}
std::ostream& Endangered::print( std::ostream &out ) const {
// thsi would be fine
// return out << "I Aa Printing Endangered" << std::endl;
out << "I Aa Printing Endangered" << std::endl;
return out;
}
#endif
// Bear
#ifndef BEAR
#define BEAR
#include "ZooAnimal.h"
#include <iostream>
class Bear : public ZooAnimal {
enum DanceType { two_left_feet, macarena, fandango, waltz };
public:
Bear();
//listing all arguments
// passing BaseClass constructor in initialiser list
Bear(std::string name, bool onExhibit=true,
std::string family = "Bear"):
ZooAnimal(name, onExhibit, family),
ival(0), dancetype(macarena) { }
virtual std::ostream& print(std::ostream&) const;
void dance() const;
//virtual ~Bear();
private:
int ival;
DanceType dancetype;
};
#endif
std::ostream& Bear::print(std::ostream &out) const {
return out << "I am printing Bear" << std:: endl;
}
// panda
#ifndef PANDA
#define PANDA
#include <iostream>
#include "Bear.h"
#include"Endangered.h"
class Panda : public Bear, public Endangered {
public:
Panda();
Panda(std::string name, bool onExhibit=true);
// virtual ~Panda();
// mentioning virtual would not be necessary
virtual std::ostream& print(std::ostream&) const;
// mentioning virtual would not be necessary
virtual void highlight() const {
std::cout << "HIGHLIGHT: Hey I am Panda" <<std::endl;
}
};
std::ostream& Panda::print(std::ostream &out ) const {
// this would be fine
// return out << " I am printing Pandaa" << std::endl;
out << "I am printing Panda" << std::endl;
return out;
}
Panda::Panda(std::string name, bool onExhibit)
: Bear(name, onExhibit, "Panda") { }
void Bear::dance() const {
switch(dancetype) {
case two_left_feet:
std::cout << "I am doing two_left_feet"<< std::endl;
break;
case macarena:
std::cout << "I am doing macarena"<< std::endl;
break;
case fandango:
std::cout << "I am doing fandango"<< std::endl;
break;
case waltz:
std::cout << "I am doing waltz"<< std::endl;
break;
}
}
# endif
// mian
#include "Bear.h"
#include "Panda.h"
#include "ZooAnimal.h"
#include<iostream>
#include<string>
int main () {
Endangered a;
ZooAnimal b("John", true, "DiMonte");
//b.print(std::cout);
Bear c("Luigi");
c.dance();
c.print(std::cout);
Panda d("Luigi");
d.print(std::cout);
d.highlight();
d.dance();
Panda e();
}
In main.cpp you firstly included Bear.h and this file contains definition of std::ostream& Bear::print(std::ostream &out). This definition is not guarded by
#ifndef BEAR
#define BEAR
...
#endif
Second include in main is Panda.h and in Panda.h you once again include Bear.h. And because you don't guard Bear::print it is included second time and compiler fails because it doesn't know which method definition it should use.
To reduce occurrence of such errors you should include only declaration in your *.h files while all definitions should go to *.cpp
Ok the stupid answer is that you need to get rid of
//#include "Bear.h" in Panda.
so my question is now
- why?
- why dont I need to include #include "Bear.h" as Bear is part of my inheritance hierarchy? I thought the compiler needed to see the definition.