Well, Hospital is the class which has vector of patients.
FemaleIn, FemaleOut, MaleIn, MaleOut are derived classes from patients(Base class). Those classes have toString function(method). What I am trying to do is, in display method in Hospital class, I just want to display only in case of Outpatient which is parent class of FemaleOut and Maleout or Inpatient which is parent class of FemaleIn and MaleIn. From what I am thinking to call only specific method from, for example, Outpatient, I will have to know which objects in which index of vector for automatically. Is there any idea to call only toString for specific class which is, for example, FemaleIn and MaleIn where parent class is Inpatient. Thank you for your any help or suggestion.
void Hospital::determinePatientType()
{
int selection;
cout << endl;
cout << "What is the patient type?" << endl;
cout << "1. Female Inpatient" << endl;
cout << "2. Female Outpatient" << endl;
cout << "3. Male Inpatient" << endl;
cout << "4. Male Outpatient" << endl;
cout << endl;
cin >> selection;
switch(selection)
{
case 1:
patients.push_back(new FemaleIn());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 2:
patients.push_back(new FemaleOut());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 3:
patients.push_back(new MaleIn());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 4:
patients.push_back(new MaleOut());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
default:
return;
}
}
void Hospital::display(string type)
{
cout << "Patient Name Spouse Name Sex Patient Type Unit/Appt. Date Diagnosis" << endl;
cout << "===================================================================================" << endl;
if(type=="All")
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
else if(type=="Outpatient")
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
else
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
}
I think this question might be similar to How do I check if an object's type is a particular subclass in C++? .
I would propose something like:
Class Patient{
virtual bool display(string filter);
};
Class OutPatient : Patient {
bool display(string filter) override;
};
bool OutPatient::display(string filter) {
if (filter != "OutPatient")
return false;
//Do stuff
return true;
}
Class InPatient : Patient {
bool display(string filter) override;
};
// You could just make this the default definition on display on Patient
bool InPatient::display(string filter) {
return false;
}
And then:
void Hospital::display(string type)
{
for(auto& patient: patients)
patient->display(type);
}
As quick and dirty way you can use dynamic_cast to certain class pointer to detect whether given instance is of that class:
if (type == "Outpatient")
{
for(int i=0; i<patients.size(); ++i)
{
// try to cast parent class pointer to one of child class
// if one is pointer to that child class p is not nullptr
// otherwise p is nullptr
Outpatient * p = dynamic_cast<Outpatient *>(patients[i]);
if (p) {
p->toString();
}
}
}
For clean way you could use Visitor pattern
Visitor pattern implementation:
#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <utility>
class AbstractDirectionPatientsDispatcher;
class AbstractGenderPatientDispatcher;
class Patient
{
public:
virtual void accept(AbstractDirectionPatientsDispatcher &dispatcher) = 0;
virtual void accept(AbstractGenderPatientDispatcher &dispatcher) = 0;
std::string name;
};
class InPatient;
class OutPatient;
class AbstractDirectionPatientsDispatcher {
public:
virtual void dispatch(InPatient &patient) = 0;
virtual void dispatch(OutPatient &patient) = 0;
};
class FemalePatient;
class MalePatient;
class AbstractGenderPatientDispatcher {
public:
virtual void dispatch(FemalePatient &patient) = 0;
virtual void dispatch(MalePatient &patient) = 0;
};
template <typename PatientClass, typename Dispatcher>
class CRTPDispatchApplier : virtual public Patient
{
public:
void accept(Dispatcher &dispatcher) override {
dispatcher.dispatch(static_cast<PatientClass &>(*this));
}
};
class InPatient : public CRTPDispatchApplier<InPatient, AbstractDirectionPatientsDispatcher>
{
};
class OutPatient : public CRTPDispatchApplier<OutPatient, AbstractDirectionPatientsDispatcher>
{
};
class FemalePatient : public CRTPDispatchApplier<FemalePatient, AbstractGenderPatientDispatcher>
{
};
class MalePatient : public CRTPDispatchApplier<MalePatient, AbstractGenderPatientDispatcher>
{
};
class InFemale : public FemalePatient, public InPatient
{
};
class OutFemale : public FemalePatient, public OutPatient
{
};
class InMale : public MalePatient, public InPatient
{
};
class OutMale : public MalePatient, public OutPatient
{
};
class DummyDirectionDispatecher : public AbstractDirectionPatientsDispatcher
{
public:
void dispatch(InPatient & ) override {
}
void dispatch(OutPatient & ) override {
}
};
class DummyGenderDispatcher : public AbstractGenderPatientDispatcher
{
public:
void dispatch(FemalePatient &) override {
}
void dispatch(MalePatient &) override {
}
};
template <typename Direction>
class DispatchByDirection : public DummyDirectionDispatecher
{
public:
DispatchByDirection(std::function<void(Direction &)> action) :
m_action(std::move(action))
{}
void dispatch(Direction & p) override {
m_action(p);
}
private:
std::function<void(Direction &)> m_action;
};
template <typename Gender>
class DispatchByGender : public DummyGenderDispatcher
{
public:
DispatchByGender(std::function<void(Gender &)> action) :
m_action(std::move(action))
{}
void dispatch(Gender & p) override {
m_action(p);
}
private:
std::function<void(Gender &)> m_action;
};
int main() {
InFemale f1;
OutFemale f2;
InMale m1;
OutMale m2;
f1.name = "Eve";
f2.name = "Alice";
m1.name = "Bob";
m2.name = "Charlie";
std::vector<Patient *> patients;
patients.push_back(&f1);
patients.push_back(&f2);
patients.push_back(&m1);
patients.push_back(&m2);
DispatchByDirection<InPatient> print_in_patients{[](InPatient &patient){
std::cout << "in: " << patient.name << std::endl;
}};
for (auto p : patients) {
p->accept(print_in_patients);
}
std::cout << std::endl;
DispatchByDirection<OutPatient> print_out_patients{[](OutPatient &patient) {
std::cout << "out: " << patient.name << std::endl;
}};
for (auto p : patients) {
p->accept(print_out_patients);
}
std::cout << std::endl;
DispatchByGender<FemalePatient> print_female{[](FemalePatient &patient) {
std::cout << "female: " << patient.name << std::endl;
}};
for (auto p : patients) {
p->accept(print_female);
}
std::cout << std::endl;
DispatchByGender<MalePatient> print_male{[](MalePatient &patient) {
std::cout << "male: " << patient.name << std::endl;
}};
for (auto p : patients) {
p->accept(print_male);
}
std::cout << std::endl;
}
Related
class CParent {
public:
void Output() {
cout << "I'm Parent!" << endl;
}
virtual void VirtualOutput() {
cout << "I'm Parent!" << endl;
}
};
class CChild : public CParent {
public:
void Output() {
cout << "I'm Child!" << endl;
}
void VirtualOutput() {
cout << "I'm Child!" << endl;
}
};
class CChildChild : public CChild {
public:
void Output() {
cout << "I'm ChildChild!" << endl;
}
void VirtualOutput() {
cout << "I'm ChildChild!" << endl;
}
void CChildOnly() {
cout << "I'm only on ChildChild!" << endl;
}
};
int main() {
CParent cp;
CChild cc;
CChildChild ccc;
CParent* pCP1 = &cp;
CParent* pCP2 = &cc;
CParent* pCP3 = &ccc;
((CChildChild*)pCP1)->CChildOnly(); //<-this code actually works. HOW? WHY?
return 0;
}
The pointer variable 'pCP1' is pointing 'cp' which is 'an object of CParent'. So the 'down casting' doesn't make any sense according to what I've learned.
But it works and shows 'I'm only on ChildChild!' with no problem.
The 'cp' has only 'CParent part' on its memory construct. So it can not be 'down casted' as far as I know.
But it works. How?
This is my code of a example program. The problem im getting is that when I add a new item to the shoppingCart array, it makes a new copy of the shoppingCart array with the present shoppingindex. How can I add all these items into the same shoppingCart array.
#include <iostream>
#include <iomanip>
using namespace std;
class Product{
private:
protected:
static int shoppingindex;
string shoppingcart[10];
public:
Product()
{
}
void displayShoppingCart() const
{
cout << endl<<endl;
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
cout << " Shopping Cart \n";
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
for(int i=0;i<10;i++)
{
// if(shoppingcart[i].length()<=1)
// {
//
// }
// else
{
cout << "\nShopping Item " <<"("<< i+1 << ")" << " - " << shoppingcart[i] << endl;
//cout << shoppingindex << endl;
}
}
}
};
class DairyProduct:public Product{
private:
protected:
public:
DairyProduct()
{
}
void AddDairyProduct(string productName)
{
shoppingcart[shoppingindex]=productName;
shoppingindex++;
}
};
class Beverages:public Product{
private:
protected:
public:
Beverage()
{
}
void AddBeverage(string productName)
{
shoppingcart[shoppingindex]=productName;
shoppingindex++;
}
};
class PersonalCare:public Product{
private:
protected:
public:
PersonalCare()
{
}
void AddPersonalCare(string productName)
{
//if conditions in all of them to match with the given dataset
shoppingcart[shoppingindex]=productName;
shoppingindex++;
}
};
class ShoppingCart{
public:
Product *object;
DairyProduct *dairy;
Beverages *bevg;
PersonalCare *personal;
ShoppingCart()
{
object = new Product; //deep copy
dairy=new DairyProduct;
bevg=new Beverages;
personal = new PersonalCare;
}
~ShoppingCart()
{
}
};
int Product::shoppingindex=0;
int main()
{
ShoppingCart user;
user.bevg->AddBeverage("Tea");
user.bevg->displayShoppingCart();
user.personal->AddPersonalCare("Shampoo");
user.personal->displayShoppingCart();
user.dairy->AddDairyProduct("Milk");
user.dairy->displayShoppingCart();
}
I am trying to understand how decorator pattern works and how much I can "stretch" it to me needs. Following this example, I have extended classes XYZ. There exist derived classes "KLM" (from XYZ)
Specifically, even though I have a decorator pattern, the derived decorator classes "KLM" have some functionality that does not show up in any of their base classes "XYZ", "D", "I" or "A".
So while normally I would instantiate an object as
I * inKLM = new L( new M( new K( new A )));
This would not allow me to access the K::doVirtR() , L::doVirtS() and M::doVirtT() functions (see code below). To access these I would need to downcast the inKLM pointer using dynamic_cast to each of classes "KLM".
The problem is that I only manage to do this for the leftmost new in the expression above. I have read that polymorphism needs to be maintained in order for the dynamic casting to work, so I have tried to have a virtual destructor in all functions. Still I cannot get the dynamic cast to work for anything other than the "outer" new operation (in this case object of class "L").
Please see this code. How can I make not only "LinKLM" , but also "MinKLM" and "KinKLM" success in dynamic_casting ?
#include <iostream>
#include <list>
using namespace std;
class D; //decorator base
struct I { //interface (for both Base and DecoratorBase
I(){
cout << "\n| I::ctor ";
}
virtual ~I(){
cout << "I::dtor |" ;
}
virtual void do_it() = 0;
virtual void regDecorator(D* decorator) = 0;
virtual void train() = 0;
virtual void et() = 0;
};
class D: public I { //DecoratorBase : has same-named fns as Base (must be exported on I) and calls upon them.
public:
D(I * inner) : m_wrappee(inner) {
cout << "D::ctor ";
regDecorator(this);
}
virtual ~D() {
cout << "D::dtor ";
delete m_wrappee;
}
void do_it() {
m_wrappee->do_it();
}
virtual void et() {
cout << "filling in for lack of et() in derived class\n";
} //almost pure virtual, just not implemented in all derived classes
void train(){
m_wrappee->train();
}
private:
void regDecorator(D* decorator){
m_wrappee->regDecorator(decorator);
}
I * m_wrappee;
};
class A: public I { //Base has all the basic functionality
public:
A() {
cout << "A::ctor " ;
decList.clear();
}
~A() {
cout << "A::dtor |" ;
}
void do_it() {
cout << 'A';
}
void train(){
et();
}
void regDecorator(D* decorator)
{
if (decorator) {
cout << "reg=" << decorator << " ";
decList.push_back(decorator);
}
else
cout << "dec is null!" <<endl;
}
private:
void et()
{
//size_t counter=0;
list<D*>::iterator it;
for( it=decList.begin(); it != decList.end(); it++ )
{
//if ( (*it)->et() )
(*it)->et();
//else
// cout << "couldnt et cnt=" << counter << endl;
//counter++;
}
}
std::list<D*> decList;
};
class X: public D { //DerivedDecoratorX ..
public:
X(I *core): D(core){
cout << "X::ctor ";
}
virtual ~X() {
cout << "X::dtor ";
}
void do_it() {
D::do_it();
cout << 'X';
}
void doX() {
cout << "doX" << endl;
}
protected:
virtual void doVirtR() = 0;
private:
void et(){
cout << "X::et" <<endl;
}
};
class K: public X {
public:
K(I * core):X(core) {
cout << "K::ctor " ;
}
virtual ~K() {
cout << "K::dtor ";
}
void doVirtR(){
cout << "doVirtK" <<endl;
}
};
class Y: public D {
public:
Y(I *core): D(core){
cout << "Y::ctor ";
}
virtual ~Y() {
cout << "Y::dtor ";
}
/*void et(){
cout << "Y::et" <<endl;
}*/
void do_it() {
D::do_it();
cout << 'Y';
}
void doY() {
cout << "doY" << endl;
}
protected:
virtual void doVirtS() = 0;
};
class L: public Y{
public:
L(I * core):Y(core) {
cout << "L::ctor ";
}
virtual ~L() {
cout << "L::dtor ";
}
void doVirtS(){
cout << "doVirtL" <<endl;
}
};
class Z: public D {
public:
Z(I *core): D(core){
cout << "Z::ctor ";
}
virtual ~Z() {
cout << "Z::dtor ";
}
void et(){
cout << "Z::et" <<endl;
}
void do_it() {
D::do_it();
cout << 'Z';
}
void doZ() {
cout << "doZ" << endl;
}
virtual void doVirtT() = 0;
};
class M: public Z{
public:
M(I * core):Z(core) { //must add D(core) here explicitly because of virtual inheritance in M's base class (Z).
cout << "M::ctor " ;
}
virtual ~M() {
cout << "M::dtor ";
}
void doVirtT(){
cout << "doVirtM" <<endl;
}
};
int main(void) //testing dynamic casting
{
I * inKLM = new L( new M( new K( new A )));
L * LinKLM = dynamic_cast<L *>( inKLM);
M * MinKLM = dynamic_cast<M *>( inKLM);
K * KinKLM = dynamic_cast<K *>( inKLM);
cout << endl;
if ( ! MinKLM ) cout << "null MinKLM!" << endl;
if ( ! LinKLM ) cout << "null LinKLM!" << endl;
if ( ! KinKLM ) cout << "null KinKLM!" << endl;
//KinKLM->doVirtR();
//LinKLM->doVirtS();
//MinKLM->doVirtT();
//LinKLM->D::train();
//KinKLM->do_it();
//MinKLM->doZ();
delete inKLM;
cout << endl;
return 0;
}
If you need access to functionality that is unique in some of the inner classes, you may be better off (depending on the particular problem) trying mixin classes. The basic idea is to have a template class inherit its template parameter. I have simplified the classes below but the principle is clear:
#include <iostream>
// your base class
class I {
public:
virtual void do_it() {}
};
// a decorator
template <class Base>
class T1 : public Base {
public:
void do_it() {
std::cout << "T1" << std::endl;
Base::do_it();
}
void unique_in_T1() {
std::cout << "Unique in T1" << std::endl;
}
};
// another decorator
template <class Base>
class T2 : public Base {
public:
void do_it() {
std::cout << "T2" << std::endl;
Base::do_it();
}
void unique_in_T2() {
std::cout << "Unique in T2" << std::endl;
}
};
// yet another decorator
template <class Base>
class T3 : public Base {
public:
void do_it() {
std::cout << "T3" << std::endl;
Base::do_it();
}
void unique_in_T3() {
std::cout << "Unique in T3" << std::endl;
}
};
int main(int argc, const char * argv[]) {
T3<T2<T1<I>>> my_object1;
my_object1.do_it();
my_object1.unique_in_T2();
T1<T3<I>> my_object2;
my_object2.do_it();
my_object2.unique_in_T3();
return 0;
}
Your class D is not needed anymore. The main purpose of that class is to wrap the object that actually does the job while maintaining the interface of I. With mixin classes there is no wrapping anymore as it has been replaced by inheritance, hence there is no need for the D class.
Here is a link to read more.
I have a state machine sort of thing encapsulated in a class. This is done by calling a sequence of member functions in turn to do the actions. I also have several derived classes, and I want to do the same sequence on them. Is there a way I can template this code?
#include <iostream>
class MyClass {
std::string name;
public:
typedef void (MyClass::*Function)(std::ostream &ostr);
void Func1(std::ostream &ostr) { ostr << "F1" << name << std::endl; };
void Func2(std::ostream &ostr) { ostr << "F2" << std::endl; };
static Function printers[];
void Print(std::ostream &ostr);
};
MyClass::Function MyClass::printers[] = {
&MyClass::Func1,
&MyClass::Func2,
NULL
};
void MyClass::Print(std::ostream &ostr)
{
// various stuff to do before
// ...
int i = 0;
for (Function *fp = printers; *fp; fp++, i++) {
std::cerr << "Calling function " << i << std::endl;
((this)->*(*fp))(ostr);
std::cerr << "Called function " << i << std::endl;
}
// other stuff here...
}
class DerClass: public MyClass {
int index;
public:
typedef void (DerClass::*Function)(std::ostream &ostr);
void Func3(std::ostream &ostr) { ostr << "F3" << index << std::endl; };
static Function printers[];
void Print(std::ostream &ostr);
};
DerClass::Function DerClass::printers[] = {
&DerClass::Func1,
&DerClass::Func3,
NULL
};
// I'd rather not repeat all this stuff, can I template it??
void DerClass::Print(std::ostream &ostr)
{
// various stuff to do before
// ...
int i = 0;
for (Function *fp = printers; *fp; fp++, i++) {
std::cerr << "Calling function " << i << std::endl;
((this)->*(*fp))(ostr);
std::cerr << "Called function " << i << std::endl;
}
// other stuff here...
}
int main()
{
MyClass cl1;
cl1.Print(std::cout);
DerClass cl2;
cl2.Print(std::cout);
}
The code runs, and works, but I'd like to write the Print routine just once, rather than for each new class, is there a way to do that, templates? Other classes?
I was hoping for something like
template <class T>
void T::Print(std::ostream &str) {
int i = 0;
for (Function *fp = printers; *fp; fp++, i++) {
std::cerr << "Calling function " << i << std::endl;
((this)->*(*fp))(ostr);
std::cerr << "Called function " << i << std::endl;
}
}
That doesn't compile though.
error: invalid use of template type parameter âTâ void
T::Print(std::ostream &str) {
I would rather write this as a comment, but the amount of code wouldn't be readable at all.
Below you can find a possible solution on how to "inherit" your Print.
This should only be taken as suggestion or hint. Especially the initialization of the printers is not really done in "a good way".
Hope it helps you nonetheless
#include <iostream>
#include <string>
template <class Derived>
class MyClass {
std::string name;
protected:
typedef void (Derived::*Function)(std::ostream &ostr);
Function* printers;
public:
MyClass()
:printers(nullptr)
{
}
~MyClass()
{
delete[] printers;
}
virtual void initPrinters()
{
if (printers == nullptr)
{
printers = new Function[3];
printers[0] = &MyClass<Derived>::Func1;
printers[1] = &MyClass<Derived>::Func2;
printers[2] = NULL;
}
}
void destroyPrinters()
{
if (printers != nullptr)
{
delete[] printers;
}
}
void Print(std::ostream &ostr)
{
initPrinters();
// various stuff to do before
// ...
int i = 0;
for (Function *fp = printers; *fp; fp++, i++) {
std::cerr << "Calling function " << i << std::endl;
(((Derived*)this)->*(*fp))(ostr);
std::cerr << "Called function " << i << std::endl;
}
// other stuff here...
}
void Func1(std::ostream &ostr) { ostr << "F1" << name << std::endl; };
void Func2(std::ostream &ostr) { ostr << "F2" << std::endl; };
};
template <>
class MyClass<void> : public MyClass<MyClass<void>>
{
};
class DerClass : public MyClass<DerClass> {
int index;
public:
virtual void initPrinters() override
{
if (printers == nullptr)
{
printers = new Function[3];
printers[0] = &DerClass::Func1;
printers[1] = &DerClass::Func3;
printers[2] = NULL;
}
}
void Func3(std::ostream &ostr) { ostr << "F3" << index << std::endl; };
};
int main()
{
MyClass<void> cl1;
cl1.Print(std::cout);
DerClass cl2;
cl2.Print(std::cout);
}
EDIT: Second Approach
This one is prettier in my opinion. Also it is less code and it can be optimized by the compiler:
#include <iostream>
#include <string>
class MyClass {
std::string name;
protected:
template <class T>
void print(std::ostream &ostr, void(T::*printFunc)(std::ostream&))
{
(((T*)this)->*printFunc)(ostr);
}
template <class T, typename... PrintFunctions>
void print(std::ostream &ostr, void(T::*printFunc)(std::ostream&), PrintFunctions... printFuncs)
{
(((T*)this)->*printFunc)(ostr);
print(ostr, printFuncs...);
}
public:
virtual void Print(std::ostream &ostr)
{
print(ostr, &MyClass::Func1, &MyClass::Func2);
}
void Func1(std::ostream &ostr) { ostr << "F1" << name << std::endl; };
void Func2(std::ostream &ostr) { ostr << "F2" << std::endl; };
};
class DerClass : public MyClass {
int index;
public:
virtual void Print(std::ostream &ostr) override
{
print(ostr, &DerClass::Func1, &DerClass::Func3);
}
void Func3(std::ostream &ostr) { ostr << "F3" << index << std::endl; };
};
int main()
{
MyClass cl1;
cl1.Print(std::cout);
DerClass cl2;
cl2.Print(std::cout);
}
If "various stuff" and "other stuff" are different, you can make those parts virtual.
But you can't call a member function of a subclass in the base class, the functions all need to have the same type.
One suggestion might be to indirect through free functions.
class MyClass;
typedef void (*Printer)(MyClass*, std::ostream&);
class MyClass {
std::string name;
public:
MyClass();
void Func1(std::ostream &ostr) { ostr << "F1" << name << std::endl; };
void Func2(std::ostream &ostr) { ostr << "F2" << std::endl; };
void Print(std::ostream &ostr);
protected:
MyClass(Printer* ps) : myprinters(ps) {}
virtual void PrePrint() { /* Various stuff... */ }
virtual void PostPrint() { /* Other stuff... */ }
private:
Printer* myprinters;
};
void MyFunc1(MyClass* obj, std::ostream& os) { obj->Func1(os); }
void MyFunc2(MyClass* obj, std::ostream& os) { obj->Func2(os); }
Printer myclassprinters[] = {
&MyFunc1,
&MyFunc2,
NULL
};
MyClass::MyClass()
: myprinters(myclassprinters)
{
}
void MyClass::Print(std::ostream &ostr)
{
PrePrint();
int i = 0;
for (Printer *fp = myprinters; *fp; fp++, i++) {
std::cerr << "Calling function " << i << std::endl;
(*fp)(this, ostr);
std::cerr << "Called function " << i << std::endl;
}
PostPrint();
}
class DerClass: public MyClass {
public:
DerClass();
void Func3(std::ostream &ostr) { ostr << "F3" << index << std::endl; };
protected:
void PrePrint() { /* More stuff... */ }
};
// C-cast for conciseness only. Use something safer in the real world.
void DerFunc(MyClass* obj, std::ostream& ostr) { ((DerClass*)obj)->Func3(ostr); }
Printer derclassprinters[] = {
&MyFunc1,
&DerFunc,
NULL
};
DerClass::DerClass()
: MyClass(derclassprinters)
{
}
This uses a pointer member for each instance - I'm assuming you don't want to store the entire function table for every instance.
I have been trying to compile this code. It has a class called books which and other genre of books inherit from it. However, when i compile the program it keeps saying Book is an inaccessible base of Police. Then it shows red lines under the first two add_book calls in the main where they add new Police.
I dont see where there is lack of access in my code?
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Book{
public:
virtual double calc_price()const;
Book(string t, string a, int pg, bool bs)
: title(t), author(a), pages(pg), bestseller(bs){}
virtual ~Book(){};
virtual void display() const;
protected:
string title;
string author;
int pages;
bool bestseller;
};
void Book::display() const {
cout << "Title: " << title << endl;
cout << "Author: " << author << endl;
cout << "Number of pages: " << pages << endl;
cout << "Bestseller: "; if(bestseller==true){ cout << "Yep"
<< endl; } else {cout << "Nope" << endl;
cout << "Price: " << calc_price() << endl; }
}
double Book::calc_price() const {
if(bestseller==true){ return (pages*0.3 + 50); }
else { return (pages*0.3); }}
class Roman : public Book {
public:
Roman(string t, string a, int pg, bool bs, bool bio)
: Book(t,a,pg,bs), biography(bio){}
virtual ~Roman();
virtual void display()const override;
protected:
bool biography;
};
void Roman::display() const{
Book::display();
cout << "Ce roman ";
if(biography==true){ cout << "is a biography. " << endl;
} else { cout << "isn't a biography. " << endl; }
}
class Police : Roman {
public:
Police(string t, string a, int pg, bool bs, bool bio)
: Roman(t,a,pg,bs,bio){}
virtual double calc_price() const {
double price;
price = Book::calc_price() - 10;
if(price < 0) { return 1; } else { return price; }}
virtual~Police();
};
class Fantasy : public Livre {
public:
Fantasy(string t, string a, int pg, bool bs)
: Book(t,a,pg,bs){}
virtual ~Fantasy();
virtual double calc_price() const {
return (Book::calc_price() + 30); }
};
class Library{
public:
void display() const;
void add_book(Book* l);
void empty_stock();
private:
vector<Book*> books;
};
void Library::add_book(Book* b){
books.push_back(b);
}
void Library::display() const {
for(size_t i(0); i < books.size(); ++i){
books[i]->display();
} }
void Library::empty_stock(){
for(size_t i(0); i < books.size(); ++i){
delete books[i]; } books.clear();
}
int main()
{
Library l;
l.add_book(new Police("Dogs of Baskerville", "A.C.Doyle", 221, false,false));
l.add_book(new Police("Le Parrain ", "A.Cuso", 367, true, false));
l.add_book(new Roman("Book3", "I. Calvino", 283, false, false));
l.add_book(new Roman ("Geronimoe memories", "S.M. Barrett", 173, false, true));
l.add_book(new Fantasy ("European rivers", "C. Osborne", 150, false));
l.display();
l.empty_stock();
return 0;
}
Change class Police : Roman in class Police : public Roman.
If public is not specified, the Roman will be a private base class for Police.
Change this line
class Police : Roman {
to
class Police : public Roman {