How to override Function in C++ - c++

Currently, I am working on c++ project I want to know how I can send an instance of a child class to function use parent as a parameter and execute a function in a child here is an example: I want Child print function to be called
Parent.h
#ifndef UNTITLED_PARENT_H
#define UNTITLED_PARENT_H
class Parent {
public:
virtual void printData();
};
#endif
Parent.cpp
#include "Parent.h"
#include <iostream>
using namespace std;
void Parent::printData() {
cout<<"Parent"<<endl;
}
Child.h
#ifndef UNTITLED_CHILD_H
#define UNTITLED_CHILD_H
#include "Parent.h"
class Child : public Parent{
public:
void printData();
};
#endif
Child.cpp
#include "Child.h"
#include <iostream>
using namespace std;
void Child::printData() {
cout<<"Child"<<endl;
}
ParentUser.h
#ifndef UNTITLED_PARENTUSER_H
#define UNTITLED_PARENTUSER_H
#include "Parent.h"
class ParentUser {
public:
void printer(Parent p);
};
#endif
ParentUser.cpp
#include "ParentUser.h"
void ParentUser::printer(Parent p) {
p.printData();
}
main.cpp
#include <iostream>
#include "Parent.h"
#include "Child.h"
#include "ParentUser.h"
int main() {
Child child;
ParentUser parentUser;
parentUser.printer(child);
return 0;
}

Your function void printer(Parent p); will create a new object of type Parent using a copy constructor your compiler automagically creates for you. You need to change it to take a reference instead:
void printer(Parent& p);
This will make sure that p is actually a reference to child, not a new Parent created from child using a copy constructor.
What's happening here is also called object slicing, as the copy is a parent type, which does not have any of the members defined in the child class.

Related

How can I fix this callback include problem?

I am kind of new to C++ (and StackOverflow). I am trying to get something to work, but I have some #include problems.
I want to call a callback I made (from here), but I am struggling to do this.
This is my code so far. When I include child.hpp in the someclass.hpp file (because it needs information about Child for Callback<Child>), it has a looped include and the compiler crashes.
I have read about forward declarations (would be class Child; in the someclass.hpp file), and after trying I figured out this works, but I also read different opinions about this.
I have all .hpp files guarded with #ifndef CLASSNAME #define CLASSNAME ... #endif
Do I need to change my entire design, or what is the best option in my case?
base.hpp
#include "someclass.hpp"
class Base
{
protected:
unique_ptr<SomeClass> someClass;
};
base.cpp
#include "base.hpp"
Base::Base()
{
this->someClass = make_unique<SomeClass>();
}
child.hpp
#include "base.hpp"
class Child : public Base
{
public:
void callbackFunction(std::string data);
unique_ptr<Callback<Child>> callback;
};
child.cpp
#include "child.hpp"
void Child::callbackFunction(std::string data)
{
/*does something*/
}
Child::Child()
{
this->callback = make_unique<Callback<Child>>(this, &Child::callbackFunction);
//I can call this->callback->call(data); here without problems
this->someClass->setCallback(this->callback);
//^^^^^^^^^^^^^^^ == base.someClass
}
someclass.hpp
#include "child.hpp" // < does crash compiler due to loop
//> someclass.hpp uses child.hpp
//> child.hpp uses base.hpp
//> base.hpp uses someclass.hpp
// and thus loop
class SomeClass
{
public:
void someFunction(std::string data);
void setCallback(unique_ptr<Callback<Child>> callback);
unique_ptr<Callback<Child>> callbackInstance;
};
someclass.cpp
//not 100% sure about the type of this parameter
void setCallback(unique_ptr<Callback<Child>> callback)
{
this->callbackInstance = callback;
}
void SomeClass::someFunction(std::string data)
{
//here I want to call this "Child::callbackFunction" which should go like "this->callbackInstance->call(data)" ?
}
also in someclass.hpp
template<class T>
class Callback
{
public:
Callback(T* instance, void (T::*function)(std::string))
{
this->callbackInstance = instance;
this->callback = function;
}
void call(std::string data)
{
(callbackInstance->*callback)(data);
}
private:
T *callbackInstance;
void (T::*callback)(std::string);
};
To solve the mentioned error("expected class-name before '{' token on child.hpp") you should remove the #include "someclass.hpp" from base.hpp and replace it with a forward declaration for class SomeClass as shown below.
base.hpp
#ifndef BASE_H
#define BASE_H
//NO NEED TO INCLUDE someclass.hpp
#include <memory>
class SomeClass;//FORWARD DECLARE SomeClass
class Base
{
std::unique_ptr<SomeClass> someClass;
public:
//add declaration for default constructor
Base();
};
#endif
base.cpp
#include "base.hpp"
#include "someclass.hpp"
//other things here
Base::Base()
{
this->someClass = std::make_unique<SomeClass>();
}
child.hpp
#ifndef CHILD_H
#define CHILD_H
#include "base.hpp"
#include <memory>
#include "someclass.hpp"
class Child : public Base
{
public:
void callbackFunction(std::string data);
std::unique_ptr<Callback<Child>> callback;
//add declaration for default constrcutor
Child();
};
#endif
child.cpp
#include "child.hpp"
void Child::callbackFunction(std::string data){
/*does something*/
}
Child::Child()
{
this->callback = std::make_unique<Callback<Child>>(this, &Child::callbackFunction);
//I can call this->callback->call(data); here without problems
}
someclass.hpp
#ifndef SOMECLASS_H
#define SOMECLASS_H
#include <string>
//REMOVED include child.hpp from here
class SomeClass
{
public:
void someFunction(std::string data);
//I think I need an instance of Callback<Child> here?
};
template<class T>
class Callback
{
public:
Callback(T* instance, void (T::*function)(std::string))
{
this->callbackInstance = instance;
this->callback = function;
}
void call(std::string data)
{
(callbackInstance->*callback)(data);
}
private:
T *callbackInstance;
void (T::*callback)(std::string);
};
#endif
someclass.cpp
#include "someclass.hpp"
void SomeClass::someFunction(std::string data)
{
//here I want to call this "Child::callbackFunction" which should go like "this->callbackInstance->call(data)" ?
}
The above program compiles and executes successfully as can be seen here.
Summary
Some of the changes that i made are listed below:
Removed unnecessary includes
Added declarations for default constructor in child.hpp and base.hpp
Added include guards in all headers.

"identifier is undefined" when calling functions defined in class (separate cpp file) from main

I'm very new to c++ and to my understanding if i include the header file which is where the functions are defined, i should be able to call the functions from main? I have tried to add static or public before the functions but nothing seemed to change.
//heres my main
#include "pch.h"
#include "myfile1.h"
#include <iostream>
using namespace std;
int main(void){
function1();
function2();
}
//my myfile1 header
#ifndef myfile1_h
#define myfile1_h
#include <iostream>
using namespace std;
class myClass{
void function1();
void function2();
};
#endif
//my myfile1.ccp
#include "myfile1.h"
#include <iostream>
using namespace std;
class myClass{
void function1() {
}
void function2() {
}
}
Your functions are in the myClass in myfile1. You must create object from this class, and you can use functions where in the this class. My English skills are not good but you must do this:
int main(void){
myClass myClassObject;
myClassObject.function1();
myClassObject.function2();
}
If you dont want create object from this class, you can do that :
myfile1.h:
#ifndef myfile1_h
#define myfile1_h
#include <iostream>
using namespace std;
void function1();
void function2();
#endif
myfile1.cpp:
#include "myfile1.h"
void function1(){
cout<<"function1"<<endl;
}
void function2(){
cout<<"function2"<<endl;
}
and main:
#include "myfile1.cpp"
int main(){
function1();
function2();
return 0;
}
If you want this functions with class, you can do it for good case:
myfile1.h
#ifndef myfile1_h
#define myfile1_h
#include <iostream>
using namespace std;
class myClass{
public: // If you want access these functions, you must use public tag.
// If you dont use any tag, it will be private, because default tag is private.
void function1();
void function2();
};
#endif
myfile1.cpp
#include "myfile1.h"
void myClass::function1(){
cout<<"function1";
}
void myClass::function2(){
cout<<"function2";
}
main:
#include "myfile1.h"
int main(){
myClass myClassObject;
myClassObject.function1();
myClassObject.function2();
return 0;
}
What is your compiler or editor? If you compile that codes from terminal, you must compile it like this:
g++ main.cpp myfile1.cpp
My English skills are not good. But I tried to explain.

Access by "a pointer of the base class" to a method or attribute of the child class which was not declared in the base class(dynamically)

during one of our assignments in C++ programming ( Inheritance), I had to design an abstract class Shape with some attributes like color, rotate degree and etc, Which are common between shapes. However, during the implementation of Base classes like Circle, Rectangle and ... I had to add some attributes like Center of the circle (which it self-required its own setter and getter cause it's private ! ) or 4 corners of the rectangle (with its setter and getter ) which were not mentioned as a function(whether virtual or not) in out Base class.
Originally I wanted to have access to every method of derived class using a pointer of the base class.In my main, I used a Pointer of my base class, Shape * to have a Dynamic Bind to the common methods and attributes, but when it comes to setting the separate (uncommon between derived and base) attributes, it's not accessible via Pointer of the base class. I tried to declare them as virtual functions in my Base class, however, it doesn't work and it's also illogical, as the user might have many characteristics in one shape!
Does any one have any idea how can this problem be solved?
and how can I have access to those mentioned methods and attributes that are only declared in the Derived class, using Shape*?
tnx
this is my base class for shapes.
class Shape
{
public:
virtual void set_color(int color)=0;
virtual void set_border_color(int border_color)=0;
virtual void set_degree(float border_width)=0;
virtual void set_border_width(double rotate_degree)=0;
virtual void set_opacity(double opacity)=0;
protected:
int color;
int border_color;
float border_width;
double rotate_degree;
double opacity;
};
respectively are my Circle and Rectangle class
circle Header:
#ifndef CIRCLE_H
#define CIRCLE_H
#include "shape.h"
class Circle :public Shape
{
public:
void set_color(int _color);
void set_border_color(int _border_color);
void set_degree(float rotate_degree);
void set_border_width(double border_width);
void set_opacity(double _opacity);
virtual void set_x_center(int _x_center);
virtual void set_y_center(int _y_center);
virtual void set_radius(int _radius);
virtual void set_name(std ::string _name);
int get_color();
int get_x_center();
int get_y_center();
std::string get_name();
private:
int x_center;
int y_center;
int radius;
std ::string name;
};
#endif // CIRCLE_H
circle CPP:
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include "circle.h"
#include "shape.h"
void Circle::set_color(int _color){ color=_color;}
void Circle::set_border_color(int _border_color){border_color=_border_color;}
void Circle::set_degree(float _rotate_degree){rotate_degree=_rotate_degree;}
void Circle::set_border_width(double _border_width){border_width=_border_width; }
void Circle::set_opacity(double _opacity){opacity=_opacity;}
int Circle::get_color(){return color;}
void Circle::set_x_center(int _x_center){ x_center=_x_center;}
void Circle::set_y_center(int _y_center){ y_center=_y_center;}
void Circle::set_radius(int _radius){ radius=_radius;}
void Circle::set_name(std ::string _name){ name=_name;}
int Circle::get_x_center(){return x_center;}
int Circle::get_y_center(){return y_center;}
std::string Circle::get_name(){return name;}
rectangle HEADER:
#ifndef RECT_H
#define RECT_H
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include "rect.h"
#include "shape.h"
class Rect : public Shape
{
public:
void set_color(int _color);
void set_border_color(int _border_color);
void set_degree(float _border_width);
void set_border_width(double _rotate_degree);
void set_opacity(double _opacity);
void set_first_point(int _first_x,int _first_y);
void set_second_point(int _second_x,int _second_y);
void set_name(std ::string _name);
private:
int first_point [2];
int second_point [2];
std ::string name;
};
#endif // RECT_H
rectangle CPP:
#include "rect.h"
#include "shape.h"
void Rect::set_color(int _color){ color=_color;}
void Rect::set_border_color(int _border_color){border_color=_border_color;}
void Rect::set_degree(float _border_width){border_width=_border_width;}
void Rect::set_border_width(double _rotate_degree){rotate_degree=_rotate_degree;}
void Rect::set_opacity(double _opacity){opacity=_opacity;}
void Rect::set_first_point(int _first_x,int _first_y){first_point[0]=_first_x;first_point[1]=_first_y;}
void Rect::set_second_point(int _second_x,int _second_y){second_point[0]=_second_x;second_point[1]=_second_x;}
void Rect::set_name(std ::string _name){name=_name;}
and here is my main
#include <cstdlib>
#include <vector>
#include <cmath>
#include <string>
#include <vector>
#include <cmath>
#include <sstream>
#include <iostream>
#include <algorithm>
#include "shape.h"
#include "circle.h"
using namespace std;
int main()
{
Circle a;
Shape* b;
b=&a;
b->set_color(12);
b->set_x_center(30);
cout<< b->get_x_center();
return 0 ;
}
Originally I wanted to have access to every method of derived class using a pointer of the base class.
You can do so by dynamic casting back to the Circle *:
b->set_color(12);
dynamic_cast<Circle *>(b)->set_x_center(30);
std::cout << dynamic_cast<Circle *>(b)->get_x_center();
This works already, however, when dynamic casting like this make sure the result is not a nullptr
b->set_color(12);
Circle *c = dynamic_cast<Circle *>(b);
if (c != nullptr)
{
c->set_x_center(30);
std::cout << c->get_x_center();
}

Instance of Forward declared Class

It's the follow up question of this: error C2504 circular inclusion.
Child if forward declared in parent's header.
It is not included, so the complier wont find Child? Then how do i instantiate a new Child object from Parent object.
Parent.h
#pragma once
#include <vector>
using std::vector;
class Child;
class Parent
{
public:
Parent();
void GiveBirth();
~Parent();
vector<Child*> children;
};
Parent.cpp
#include "stdafx.h"
#include "Parent.h"
Parent::Parent()
{
}
void Parent::GiveBirth()
{
Child ch = Child(); //Error: incomplete type is not allowed
}
Parent::~Parent()
{
}
Child.h
#pragma once
#include "Parent.h"
class Child : Parent
{
public:
Child();
~Child();
};
Child.cpp
#include "stdafx.h"
#include "Child.h"
Child::Child()
{
}
Child::~Child()
{
}
Here are some reading list for you.
http://en.wikipedia.org/wiki/Opaque_pointer
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Idioms#Pointer_To_Implementation_.28pImpl.29
Parent.cpp
#include "stdafx.h"
#include "Parent.h"
#include "Child.h"
Parent::Parent()
{
}
void Parent::GiveBirth()
{
//Child ch = Child(); //Error: incomplete type is not allowed
children.push_back(new Child());
}
Parent::~Parent()
{
}

Arduino: Inheritance and arrays of pointer subclasses

This is problem #2 from this previous question:
Inheritance in Arduino Code
Building off of Steven's answer, I do need the array that holds the pointers to persist outside of its scope, which is resulting in some weird behavior.
This is my "Board" class I have so far, that contains multiple child elements:
Board.h:
#ifndef Board_h
#define Board_h
#include <StandardCplusplus.h>
#include <serstream>
#include <string>
#include <vector>
#include <iterator>
#include "Arduino.h"
#include "Marble.h"
#include "Wall.h"
class Board
{
public:
Board();
void draw(double* matrix);
private:
Marble marble;
//std::vector<Actor> children;
Actor* children[2];
};
#endif
Board.cpp:
#include "Arduino.h"
#include "Board.h"
#include <math.h>
#include <iterator>
#include <vector>
Board::Board()
{
}
void Board::create(double* _matrix, int _cols, int _rows) {
Marble *marble = new Marble();
Wall wall;
children[0] = marble;
//children.push_back(marble);
//children.push_back(wall);
}
void Board::draw(double* matrix) {
Serial.println("board draw");
children[0]->speak();
}
In my "loop" function I am calling
board.draw(matrix);
which results in some nutty Serial code being written out.
Clearly I am not understanding the ins and outs of pointers in arrays in classes here.
You need to make Actor::speak virtual, the compiler uses dynamic binding for virtual methods.
class Actor
{
public:
Actor();
virtual void speak(); // virtual
private:
};