I am new to Design Pattern, and I'm trying the first example of (Head First Design Patterns) but I'm trying to code it in C++. I can't compile my code! I don't know why. Here's my code.
#include <iostream>
using namespace std;
class QuackBehavior
{
public:
virtual void quack();
virtual ~QuackBehavior();
};
class Quack : public QuackBehavior
{
public:
void quack()
{
cout<<"Quacking"<<endl;
}
};
class MuteQuack : public QuackBehavior
{
public:
void quack()
{
cout<<"<<< Silence >>>"<<endl;
}
};
class Squeak : public QuackBehavior
{
public:
void quack()
{
cout<<"Squeak"<<endl;
}
};
class FlyBehavior
{
public:
virtual void fly();
virtual ~FlyBehavior();
};
class FlyWithWings : public FlyBehavior
{
public:
void fly()
{
cout<<"I'm flying"<<endl;
}
};
class FlyNoWay : public FlyBehavior
{
public:
void fly()
{
cout<<"I can't fly"<<endl;
}
};
class Duck
{
public:
FlyBehavior *flyBehavior;
QuackBehavior *quackBehavior;
void display();
void performFly()
{
flyBehavior->fly();
}
void performQuack()
{
quackBehavior->quack();
}
};
class MallardDuck : public Duck
{
public:
MallardDuck()
{
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
};
int main()
{
Duck *mallard = new MallardDuck;
cout<<"Test"<<endl;
mallard->performFly();
// mallard->performQuack();
return 0;
}
Thanks for your help.
You get a compile error because you have not provided default definitions for functions in class QuackBehavior and class FlyBehavior.
Either you could provide default implementation or make the functions pure virtual.
Make the below two changes and your code should compile fine.
class QuackBehavior
{
public:
virtual void quack(){}
virtual ~QuackBehavior(){}
};
class FlyBehavior
{
public:
virtual void fly(){}
virtual ~FlyBehavior(){}
};
OR
class FlyBehavior
{
public:
virtual void fly() = 0;
};
class QuackBehavior
{
public:
virtual void quack() = 0;
};
Related
I have a class hierarchy like:
class A {
list<A*> children;
public:
void update() {
do_something();
update_current();
for(auto child : children)
children->update();
}
protected:
virtual void update_current() {};
};
class B : public A {
protected:
void update_current() override {
do_something_important();
};
};
class C1 : public B {
protected:
void update_current() override {
B::update_current();
do_something_very_important();
};
};
class C2 : public B {
protected:
void update_current() override {
B::update_current();
do_something_very_important_2();
};
};
int main() {
A* a = new A();
//fill a's childred list somehow
while(come_condition) {
//some code
a.update();
//something else
}
return 0;
}
The question is: how can I remove duplicate B::update_current(); calls from derived classes without changing program's behaviour? Is it possible or are there no solutions except calling base class functions manually? Thank you.
You could make B's children override a different function:
class B : public A {
protected:
void update_current() override final {
do_something_important();
do_something_important_later();
};
virtual void do_something_important_later() = 0;
};
With:
class C2 : public B {
protected:
void do_something_important_later() override {
do_something_very_important_2();
};
};
I want to expose only the functions from the Abstract Class that have been overridden (implemented) by the derived Class.
For example: I have an Abstract Class called Sensor that is implemented by various different types of sensors. Some have more capabilities than others, so I don't want all functions to be exposed. Only the ones implemented. In the following example all sensors can produce DataA, but DataB and DataC are sensor specific. Some can produce all three, some 2 and some only DataA.
//Code Example
class Sensor{
public:
virtual DataContainer* getDataA() = 0; //pure virtual
virtual DataContainer* getDataB() {return null_ptr;}; //but this would appear in the derived objects
virtual DataContainer* getDataC() {return null_ptr;};
}
class SensorA : public Sensor {
public:
virtual DataContainer* getDataA(){
//code
}
}
class SensorAB : public Sensor {
public:
virtual DataContainer* getDataA(){
//code
}
virtual DataContainer* getDataB(){
//code
}
}
//main
Sensor* ab = new SensorAB();
ab->getDataB(); //GOOD
ab->getDataC(); // Not possible
Is there any way to achieve this?
You need more deep class hierarchy.
class Sensor...
class SensorA: virtual public Sensor...
class SensorB: virtual public Sensor...
class SensorAB: public SensorA, public SensorB...
Do not forget about virtual keyword.
Example:
class Sensor {
public:
virtual ~Sensor() {}
template<typename T>
bool CanConvert()
{
return dynamic_cast<T*>(this) != nullptr;
}
template<typename T>
T& Convert()
{
return dynamic_cast<T>(*this);
}
};
class SensorA: virtual public Sensor {
public:
virtual void DataA() = 0;
};
class SensorB: virtual public Sensor {
public:
virtual void DataB() = 0;
};
class SensorC: virtual public Sensor {
public:
virtual void DataC() = 0;
};
class SensorAB: public SensorA, public SensorB {
public:
void DataA() override {
std::cout << "SensorAB::DataA()" << std::endl;
}
void DataB() override {
std::cout << "SensorAB::DataB()" << std::endl;
}
};
Than you can use it:
void Func(Sensor& s)
{
if (s.CanConvert<SensorA>()) {
auto &s_a = s.Convert<SensorA>();
s_a.DataA();
}
if (s.CanConvert<SensorB>()) {
auto &s_b = s.Convert<SensorB>();
s_b.DataB();
}
if (s.CanConvert<SensorC>()) {
auto &s_c = s.Convert<SensorC>();
s_c.DataC();
}
}
...
SensorAB s_ab;
Func(s_ab);
Or you can use static polymorphysm. Create base class for every data type: SensorA, SensorB, SensorC. Than compose sensor with desired interface (SensorAB for example):
template <class Derived>
class SensorA
{
public:
void DataA() { static_cast<Derived*>(this)->DataAImpl(); }
};
template <class Derived>
class SensorB
{
public:
void DataB() { static_cast<Derived*>(this)->DataBImpl(); }
};
template <class Derived>
class SensorC
{
public:
void DataC() { static_cast<Derived*>(this)->DataCImpl(); }
};
class SensorAB: public SensorA<SensorAB>, public SensorB<SensorAB>
{
public:
void DataAImpl()
{
std::cout << "SensorAB::DataAImpl()" << std::endl;
}
void DataBImpl()
{
std::cout << "SensorAB::DataBImpl()" << std::endl;
}
};
Than you can use it:
SensorAB s_ab;
s_ab.DataA();
s_ab.DataB();
And you can use power of compilation time type check. But in this case you can cast only to SensorAB if you have base Sensor class, not in SensorA or SensorB.
So I have two classes. One has only purely virtual functions. THe other implements those functions and is derived from the first class.
I get that i cant instantiate the first class. But when I try to create an object of the second class it fails as well.
This is how my second class looks in general:
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
}
Implementation:
SecondClass::SecondClass()
{...}
SecondClass::~SecondClass(void)
{...}
void SecondClass::Foo()
{...}
void SecondClass::Bar()
{...}
This how I instantiate it and get the Error:
SecondClass mSecClass;
Where am I going wrong here?
FirstClass.h
class FirstClass
{
public:
FirstClass(void);
virtual ~FirstClass(void);
virtual void Foo() = 0;
virtual void Bar() = 0;
};
You need to define the ~FirstClass() destructor and leave out its constructor
class FirstClass
{
public:
virtual ~FirstClass(void) {} // or use C++11 = default syntax
virtual void Foo() = 0;
virtual void Bar() = 0;
};
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
};
SecondClass::SecondClass() {}
SecondClass::~SecondClass(void) {}
void SecondClass::Foo() {}
void SecondClass::Bar() {}
int main()
{
SecondClass mSecClass;
}
Live Example.
Define every function you declare, except for pure virtuals(virtual void foo() = 0).
try the below code:
#include<iostream>
using namespace std;
class FirstClass
{
public:
FirstClass()
{
//
}
virtual ~FirstClass();
virtual void Foo();
virtual void Bar();
};
FirstClass::~FirstClass()
{
//
}
void FirstClass::Foo()
{
//
}
void FirstClass::Bar()
{
//
}
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
};
SecondClass::SecondClass(){
//
}
SecondClass::~SecondClass(void)
{//
}
void SecondClass::Foo()
{//
}
void SecondClass::Bar()
{//
}
int main()
{
SecondClass name;
return 0;
}
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
};
I've a problem with this pattern under c++ on VS 2008.
The same code has been tested in gcc (linux, mac and mingw for
widnows) and it works.
I copy/paste the code here:
class MyCommand {
public:
virtual void execute() = 0;
virtual ~MyCommand () {};
};
class MyOperation {
public:
virtual void DoIt() {}; //I also write it not inline
};
class MyOperationDerived : public MyOperation {
public:
virtual void DoIt() {}; //I also write it not inline
};
class MyUndoStackCommand : public MyCommand {
public:
typedef void(MyOperation::*Action)();
MyUndoStackCommand(MyOperation *rec, Action action);
/*virtual*/ void execute();
/*virtual*/ ~MyUndoStackCommand();
private:
MyOperation *myReceiver;
Action myAction ;
};
in cpp:
#include "MyUndoStackCommand.h"
#include "MyOperation.h"
MyUndoStackCommand::~MyUndoStackCommand() {
}
MyUndoStackCommand::MyUndoStackCommand(myOperation *rec, Action
action): myReceiver(rec), myAction(action) {
}
void MyUndoStackCommand::execute() {
((myReceiver)->*(myAction))();
}
use in main.cpp:
MyReceiver receiver;
MyUndoStackCommand usc(&receiver, &MyOperation::DoIt);
usc.execute();
when I debug under visual studio only if I set inside MyUndoStackCommand, directly
myAction = &MyOperation::DoIt , it works, otherwise not.
Any advice?
thank you very much,
dan
Edit: The following code compiles with g++ - changes by Neil Butterworth flagged as //NB.
class MyCommand {
public:
virtual void execute() = 0;
virtual ~MyCommand () {};
};
class MyOperation {
public:
virtual void DoIt() {}; //I also write it not inline
};
class MyOperationDerived : public MyOperation {
public:
virtual void DoIt() {}; //I also write it not inline
};
class MyUndoStackCommand : public MyCommand {
public:
typedef void(MyOperation::*Action)();
MyUndoStackCommand(MyOperation *rec, Action action);
/*virtual*/ void execute();
/*virtual*/ ~MyUndoStackCommand();
private:
MyOperation *myReceiver;
Action myAction ;
};
MyUndoStackCommand::~MyUndoStackCommand() {
}
MyUndoStackCommand::MyUndoStackCommand(MyOperation *rec, //NB
Action action)
: myReceiver(rec), myAction(action) {
}
void MyUndoStackCommand::execute() {
((myReceiver)->*(myAction))();
}
int main() {
MyOperation receiver; //NB
MyUndoStackCommand usc(&receiver, &MyOperation::DoIt);
usc.execute();
}
With Neils edit this works fine in Visual Studio 2008.
// command.h
#pragma once
#include <iostream> // added for printing
using namespace std; // added for printing
class MyCommand {
public:
virtual void execute() = 0;
virtual ~MyCommand () {};
};
class MyOperation {
public:
virtual void DoIt() {
cout << "myoperation::doit()" << endl;
}; //I also write it not inline
};
class MyOperationDerived : public MyOperation {
public:
virtual void DoIt() {
cout << "myoperationderived::doit()" << endl;
}; //I also write it not inline
};
class MyUndoStackCommand : public MyCommand {
public:
typedef void(MyOperation::*Action)();
MyUndoStackCommand(MyOperation *rec, Action action);
/*virtual*/ void execute();
/*virtual*/ ~MyUndoStackCommand();
private:
MyOperation *myReceiver;
Action myAction;
};
// command.cpp
#include "command.h"
MyUndoStackCommand::~MyUndoStackCommand() {
}
MyUndoStackCommand::MyUndoStackCommand(/*m*/ MyOperation *rec, Action
action): myReceiver(rec), myAction(action) {
}
void MyUndoStackCommand::execute() {
((myReceiver)->*(myAction))();
}
// main.cpp
#include "command.h"
int main(){
MyOperationDerived receiver;
MyUndoStackCommand usc(&receiver, &MyOperation::DoIt);
usc.execute();
}
Will print:
"myoperationderived::doit()"