if I have the following code:
class A
{
public:
virtual void Yo();
}
class B : public A
{
public:
virtual void Yo() override;
}
Is there a way to force B to implement method Yo in A? Like an interface or more specifically (in this case) an abstract?
My full code is here:
BaseObject.h
#pragma once
namespace Game
{
namespace Model
{
namespace Graphic
{
class BaseObject
{
public:
int Width;
int Height;
float X;
float Y;
float Z;
virtual void SetUp() = 0;
virtual void Reset() = 0;
};
}
}
}
Player.cpp
#include "pch.h"
#include "Abstract\BaseObject.h"
using namespace Game::Model::Graphic;
class Player : public BaseObject
{
public:
Player();
~Player();
//virtual void SetUp();
//virtual void Reset() override;
};
in A make Yo pure virtual
virtual void Yo() = 0;
a complete example
#include <iostream>
struct A
{
virtual void Yo() = 0;
};
struct B : A
{
virtual void Yo() { std::cout << "I'm B\n"; }
};
int main()
{
B b;
b.Yo();
return (0);
}
if B doesn't implement Yo this will not compile.
The override keyword it's not needed in this case.
You have to take pointer of the base class to implement virtual functions in C++. This seems quite obvious. But i think we have missed that. The most basic example is given below.
#include <iostream>
using namespace std;
class base {
public:
virtual void vfunc() {
cout << "This is base's vfunc().\n";
}
};
class derived1 : public base {
public:
void vfunc() {
cout << "This is derived1's vfunc().\n";
}
};
int main()
{
base *p, b;
derived1 d1;
// point to base
p = &b;
p->vfunc(); // access base's vfunc()
// point to derived1
p = &d1;
p->vfunc(); // access derived1's vfunc()
return 0;
}
Related
I'm trying to practice "Observer Design Pattern". When I thought a abstract's pure virtual method has been override by it's derived class, a error occurred.
There is a observer which is an abstract class in a independent file:
#ifndef DESIGN_PATTERNS_OBSERVER_H
#define DESIGN_PATTERNS_OBSERVER_H
#include "subject.h"
class Subject;
class Observer{
protected:
Observer();
public:
virtual ~Observer();
virtual void update(Subject *the_changed_subject) = 0;
};
Observer::Observer() {}
Observer::~Observer() {}
#endif //DESIGN_PATTERNS_OBSERVER_H
Observer defined a pure virtual method "update" which overrides as follow:
#ifndef DESIGN_PATTERNS_CONCRETE_OBSERVER_H
#define DESIGN_PATTERNS_CONCRETE_OBSERVER_H
#include <iostream>
#include "observer.h"
#include "concrete_subject.h"
class ConcreteObserver : public Observer{
public:
void update(Subject *the_changed_subject) override {
auto cs = dynamic_cast<ConcreteSubject *>(the_changed_subject);
std::cout << "status changed to " << cs->get_status() << std::endl;
}
};
#endif //DESIGN_PATTERNS_CONCRETE_OBSERVER_H
And also there is a subject which is an abstract class too.The error "pure virtual method called" happened in "notify" method where I had marked.
From debug, it seems "notify" uses Observer's "update" rather than ConcreteObserver's.
However,in main function the _observers should stored pointers of ConcreteObservers which override "update".
#ifndef DESIGN_PATTERNS_SUBJECT_H
#define DESIGN_PATTERNS_SUBJECT_H
#include <list>
#include "observer.h"
class Subject {
private:
std::list<Observer*> *_observers;
protected:
Subject();
public:
virtual ~Subject();
virtual void attach(Observer*);
virtual void detach(Observer*);
virtual void notify();
};
Subject::Subject() {
_observers = new std::list<Observer*>;
}
Subject::~Subject() {
delete _observers;
}
void Subject::attach(Observer *o) {
_observers->push_back(o);
}
void Subject::detach(Observer *o) {
_observers->remove(o);
}
void Subject::notify() {
for (Observer* observer : *_observers) {
//here is where error comes out, found by debug
observer->update(this);
}
}
#endif //DESIGN_PATTERNS_SUBJECT_H
And it has a derived class "ConcreteSubject":
#ifndef DESIGN_PATTERNS_CONCRETE_SUBJECT_H
#define DESIGN_PATTERNS_CONCRETE_SUBJECT_H
#include "subject.h"
class ConcreteSubject : public Subject {
private:
int status;
public:
ConcreteSubject() {
status = 0;
}
void set_status(int s) {
this->status = s;
Subject::notify();
}
int get_status() {
return status;
}
};
#endif //DESIGN_PATTERNS_CONCRETE_SUBJECT_H
The main function:
#include <iostream>
#include <vector>
#include "singleton.h"
#include "observer/concrete_subject.h"
#include "observer/concrete_observer.h"
void test2() {
ConcreteSubject concreteSubject;
std::vector<ConcreteObserver> observers;
for (int i = 0; i < 5; ++i) {
ConcreteObserver observer = ConcreteObserver();
concreteSubject.attach(&observer);
observers.push_back(observer);
}
concreteSubject.set_status(2);
}
int main() {
test2();
return 0;
}
As I mentioned before, the _observers of ConcreteSubject's super class Subject should stored pointers of ConcreteObservers which override "update" already.
I don't understand why Observer's "update" still called.
Here is another strange thing.I make a small test has almost the same relationship of classes I showed.But no error occured.
class ABaseA{
public:
virtual void do_some() = 0;
};
class MidA : public ABaseA{
public:
void do_some() override {
cout << "real do some" << endl;
}
};
class ABaseB{
private:
list<ABaseA*> *bases;
public:
ABaseB() {
bases = new list<ABaseA*>();
}
virtual ~ABaseB() = default;
virtual void add(ABaseA* item) {
bases->push_back(item);
}
virtual void do_active() {
for(ABaseA *p : *bases) {
p->do_some();
}
}
};
class MidB : public ABaseB{
public:
MidB() = default;
void active() {
ABaseB::do_active();
}
};
void test3() {
MidA midA;
MidB midB;
midB.add(&midA);
midB.active();
}
The only difference is this code is in one file.
In the file of Subject.h you should be transfer below code to Subject.cpp:
Subject::Subject() {
_observers = new std::list<Observer*>;
}
Subject::~Subject() {
delete _observers;
}
void Subject::attach(Observer *o) {
_observers->push_back(o);
}
void Subject::detach(Observer *o) {
_observers->remove(o);
}
void Subject::notify() {
for (Observer* observer : *_observers) {
//here is where error comes out, found by debug
observer->update(this);
}
}
Also you should be add class Observer; in top of Subject.h
#include <list>
#include "Observer.h"
class Observer; //you should be add this line
class Subject {
private:
std::list<Observer*> *_observers;
protected:
Subject();
public:
virtual ~Subject();
virtual void attach(Observer*);
virtual void detach(Observer*);
virtual void notify();
};
I need to assign x = 2000 to x of B via object a of A
Here B is the derived class i.e inherits the class A.
class A
{
public:
int x, y;
void print()
{
cout<<endl<<"print() of A";
}
virtual void display()
{
cout<<endl<<"display() of A";
}
};
class B: public A
{
public:
int x, z;
void display()
{
cout<<endl<<"display() of B";
}
void print()
{
cout<<endl<<"print() of B";
}
};
Found the answer by doing the following:
((B *)aptr)->x = 2000;
In C++, polymorphism is implemented via virtual functions. If you need to change something in a derived class through a pointer or reference to its base type, you need a virtual function. (Well, technically, you don't; you could cast to the derived type, but that's an admission of design failure).
It can be done by creating virtual function in base class which effect to call function of derive class for initialization.
#include<iostream>
#include<stdio.h>
using namespace std;
class A
{
public:
int x, y;
void print()
{
cout<<endl<<"print() of A";
}
virtual void display()
{
cout<<endl<<"display() of A";
}
virtual void setX(int a)
{
}
};
class B: public A
{
public:
int x, z;
void display()
{
cout<<endl<<"display() of B";
}
void print()
{
cout<<endl<<"print() of B";
}
void setX(int a)
{
x=a;
}
};
int main()
{
A *ptr;
B b;
ptr=&b;
ptr->setX(2000); ///using pointer object of class A
cout<<b.x;
}
I think it will help you :)
Is there any way to call a parent's function from a child class but within the function use data from the child instead of the parent eg.
#include <stdio.h>
class Base{
public:
int i=10;
virtual void print(){
printf("%i", i );
}
};
class Derived : public Base {
public:
int i = 20;
void print(){
Base::print();
}
};
int main (){
Derived I;
I.print();
}
So I want this to print 20 instead of 10 basically.
EDIT ::::::::::::
What I am actually trying to do is use a base class that defines multiple functions
virtual int OnExecute();
virtual bool OnInit();
virtual void OnEvent(SDL_Event* Event);
virtual void OnLoop();
virtual void OnRender();
virtual void OnCleanUp();
Then have a derived class overload all of those functions exept OnExectue() which looks like this
if (OnInit() == 0 ){
return -1;
}
SDL_Event Event;
while (isRunning){
while (SDL_PollEvent(&Event)){
OnEvent(&Event);
}
OnLoop();
OnRender();
}
OnCleanUp();
So is there a more simplistic way where i won't be having to define 5 extra functions to pass function pointers.
You can do this if you provide access to the data through a virtual member function.
#include <stdio.h>
class Base{
public:
int i=10;
virtual void print(){
printf("%i", this->getI() );
}
virtual int getI()
{
return i;
}
};
class Derived : public Base {
public:
int i = 20;
void print(){
Base::print();
}
virtual int getI()
{
return i;
}
};
int main (){
Derived I;
I.print();
}
You need a dynamic_cast , Like this:
#include <iostream>
#include <stdio.h>
class Derived;
class Base{
public:
int i=10;
virtual void print();
};
class Derived : public Base {
public:
int i = 20;
void print(){
Base::print();
}
};
void Base::print(){
Derived* p = dynamic_cast<Derived*>(this);
if(p) {
//derived
printf("%i\n", p->i);
}else{
//base
printf("%i\n", i);
}
}
int main (){
Derived I;
I.print();
}
I like the results of this code but i was curious, is it possible to call B::VFunc() from main()? I know writing B::VFunc(); inside of C will call it but is it possible to call the function from outside of the object?
http://ideone.com/Dg8aa
#include <cstdio>
class I { public: virtual void VFunc()=0; };
class B : public I { public: void VFunc() { printf("B\n"); } };
class C : public B { public: void VFunc() { printf("C\n"); } };
int main(){
C v;
B&i = v;
i.VFunc();
}
output:
C
This will do it:
#include <cstdio>
class I { public: virtual void VFunc()=0; };
class B : public I { public: void VFunc() { printf("B\n"); } };
class C : public B { public: void VFunc() { printf("C\n"); } };
int main(){
C v;
B&i = v;
i.B::VFunc();
}
Example: http://ideone.com/MfyYJ
You can resort to slicing:
C v;
B i = (B)v;
http://ideone.com/YVI2T
The dynamic type of v is lost, so B::VFunc is called.
What happens when a class inherits from multiple abstract classes when 2 or more of them have a function with the same name, return type, and arguments?
Assuming all functions here are virtual
Thanks
class C inherits from A and B at the same time and both A & B have virtual void func(int h);
If this is what you mean,
#include <iostream.h>
class A
{
public:
virtual void a_show()=0;
virtual void show()
{
cout<<"A";
}
};
class B
{
public:
virtual void b_show()=0;
virtual void show()
{
cout<<"B";
}
};
class C : public A, public B
{
virtual void a_show()
{}
virtual void b_show()
{}
};
void main()
{
C s;
s.show();
}
The code gives an error with VC++ like
error C2385: 'C::show' is ambiguous
You need to declare show like this :
#include <iostream.h>
class A
{
public:
virtual void a_show()=0;
virtual void show()
{
cout<<"A";
}
};
class B
{
public:
virtual void b_show()=0;
virtual void show()
{
cout<<"B";
}
};
class C : public A, public B
{
public:
virtual void a_show()
{}
virtual void b_show()
{}
void show()
{
cout<<"C";
}
};
void main()
{
C s;
s.show();
}
This sure will give C
C++ also allows to pick an inherited virtual member function (IVMF) as well, so you don't need to override an IVMF. Borrowing the example from mihsathe, we can do the following:
class C : public A, public B {
public:
virtual void a_show() { }
virtual void b_show() { }
using B::show;
// using A:show; // If you want to use show() from A
};