Detecting if we are in child class or base class - c++

I have a problem, and I tried to use RTTI to resolve it.
I have a class Base and children classes (in the example, I show only one Child)
class Base {
virtual void Eval() {
// normal treatment
+
// treatment only for Base instance
}
};
class Child : Base {
void Eval() {
// call Base Eval
Base::Eval();
//other treatment
}
};
The problem, is that in Base::Eval, there are some treatments which I dont't want to execute when I call it from Child.
What I mean, in Child::Eval, when we call the Base::Eval, we want only the normal treatment which is executed.
For this, I thought about RTTI. I don't know if it is the best way to use it, I thought to do something like this:
class Base {
virtual void Eval() {
// normal treatment
+
if (typeid(this).name() == typeid(Base).name()) {
// treatment only for Base instance
}
}
}
The question is: Is it permitted to do that?
Am I obliged to check typeid.name()?
Or would just typeid() be enough?

Situations such as this are almost always an indication of bad design. A base class should not know anything about its derived classes.
If you want to give derived classes an option to customise parts of the base behaviour, use virtual functions and the "template method" design pattern:
class Base
{
public:
virtual void Eval() {
// normal treatment
Eval_CustomisationHook();
}
protected:
virtual void Eval_CustomisationHook()
{
// Do the stuff
}
};
class Child : public Base
{
protected:
virtual void Eval_CustomisationHook()
{} // do nothing
};
Alternatively, you could delegate just the query:
class Base
{
public:
virtual void Eval() {
// normal treatment
if (doOptionalEvalPart()) {
// do it here
}
}
protected:
virtual bool doOptionalEvalPart()
{
return true;
}
};
class Child : public Base
{
protected:
virtual bool doOptionalEvalPart()
{
return false;
}
};
And to answer your original question as well: the correct form would be to compare the std::type_info objects, not their names. And don't forget you'd have to dereference this. So the code would look like this:
if (typeid(*this) == typeid(Base))
This will do what you want it to. But as I've said above, this is most probably not the proper approach.

Related

Is saving the type in the base class considered bad programming

I want to know the type of my class at compilation and i want to know if my idea is considered bad programming or if its actually viable. May correct me if there is a better way to realize this.
class Base {
int type = 0;
}
class Derivative : public Base{
Derivative(){
type = 1;
SomeObject1 o;
SomeAnotherObject o1;
}
}
class Derivative2 : public Base{
Derivative2(){
type = 2;
RandomObject test;
AnotherObject v;
}
}
Some method that gets myBaseClass as Base:
if(myBaseClass.type == 1){
Derivative d = static_cast<Derivative>(myBaseClass);
d.o;
d.o1;
}
if(myBaseClass.type == 2){
Derivative2 d = static_cast<Derivative2>(myBaseClass);
d.test;
d.v;
}
In my opinion it would be unusual to write virtual methods for all different Objects
Is saving the type in the base class considered bad programming
Definitely, yes!
Using a polymorphic virtual design you don't need to have that extra information stored into the base class. The compiler already does that for you:
class Base {
protected:
virtual ~Base() {} // <<<<<<<<<<<<<
}; // Note the ;!
class Derivative : public Base{
};
class Derivative2 : public Base{
};
You can always detect the real class type from a Base pointer or reference with a dynamic_cast then:
Base* pd1 = new Derivative();
Base* pd2 = new Derivative2();
if(dynamic_cast<Derivative>(pd1)) { // Yields true
}
if(dynamic_cast<Derivative>(pd2)) { // Yields false
}
Though if you need to know that, that's a serious indicator of a bad design.
You should rather introduce some interfaces in form of pure virtual function definitions:
class Base {
protected:
virtual ~Base() {}
public:
virtual void DoSomething() = 0;
};
class Derivative : public Base{
public:
void DoSomething() override {
// provide an implementation specific for Derivative
}
};
class Derivative2 : public Base{
public:
void DoSomething() override {
// provide an implementation specific for Derivative2
}
};
That allows you to call DoSomething() without knowing the specific type that implements that function:
Base* pd1 = new Derivative();
Base* pd2 = new Derivative2();
pd1->DoSomething(); // calls Derivative specific implementation
pd2->DoSomething(); // calls Derivative2 specific implementation
To make safe and efficient use of the static_cast use the CRTP instead:
template<typename Derived>
class Base {
public:
void DoSomething() {
static_cast<Derived*>(this)->DoSomething();
}
};
class Derivative : public Base<Derivative> {
};
class Derivative2 : public Base<Derivative2> {
};
Here's the (ugly) approach I used a few years back when hacking-together a pdf writer. It appears to solve exactly the same problem that you have.
pdfArray::pdfArray(const pdfArray &src)
{
vecObjPtrIter iter;
pdfObj *ptr;
mArray = new vecObjPtr;
for (iter=src.mArray->begin(); iter!=src.mArray->end(); iter++)
{
ptr = *iter;
if (typeid(*ptr) == typeid(pdfString))
addItem( (pdfString*)ptr );
if (typeid(*ptr) == typeid(pdfInt))
addItem( (pdfInt*)ptr );
if (typeid(*ptr) == typeid(pdfFloat))
addItem( (pdfFloat*)ptr );
if (typeid(*ptr) == typeid(pdfArray))
addItem( (pdfArray*)ptr );
}
}
There are uses of this technique that are at least plausible. One that I've seen involved a class hierarchy whose instances needed to be configured by the user (driven from Python) and then used in performance-critical code (in C++). The base class provided a getType() method that returned an enumeration; the wrapper code in Python called this to discover which interface to offer the user. Cross-language code often forces the use of simple-minded techniques like this based on agreed-upon integer labels.
More generally, sometimes good design principles like MVC encourage this sort of arrangement. Even if the different layers are written in the same language, it's not necessarily a good idea for the underlying model objects to have methods like makeQtWidgets(), since it requires that layer to know not only about the GUI library but also about the layout and control flow of the user interface.
A practical point: to avoid the situation where a derived class fails to specify its type, the base class should require the value in its constructor:
struct Base {
enum Type { derived1, derived2 };
Base(Type t) : typ(t) { /* ... */ }
virtual ~Base()=0;
Type getType() const {return typ;}
// ...
private:
Type typ;
};
struct Derived1 : Base {
Derived1() : Base(derived1) { /* ... */ }
// ...
};
You might as well put the enum of all possibilities in the base class, since there must already be a central registry of the value for each derived class even if it's just on paper. This is a downside beyond the several mentioned by others: this design requires that all the classes be centrally managed, with no possibility for independent extension.
Finally, despite that inflexibility the clients must always confront the ugly possibility of an object of an unexpected type:
void foo(const Base &b) {
switch(b.getType()) {
case Base::derived1: /* ... */ break;
case Base::derived2: /* ... */ break;
default:
// what goes here?
}
}

Parent class referencing child variable

I have several similar classes inheriting from the same Base-Class/Interface (Base class 1), and they share a couple similar functions, but then also have their own distinct functions. They all also have their own member variables of different classes, and each of those inherits from the same Base-Class/Interface (Base class 2). Is it possible to define a variable in Base class 1, of type Base class 2, then in the actual implementation of classes using Base class 1, have the variable of type Base class 2 be its proper type. Kinda hard to explain, so simplified example below.
//Base-Class 1
class Shape
{
public Shape() {}
ShapeExtra m_var;
//The common functions
public GetVar(){ return m_var; }
}
class Circle : Shape
{
public Circle() { m_var = new CircleExtra(); }
public void CircleFunc()
{
m_var.CircleExtraFunc();
}
}
class Triangle : Shape
{
public Triangle() { m_var = new TriangleExtra(); }
public void TriangleFunc()
{
m_var.TriangleExtraFunc();
}
}
.
.
.
//Base_Class 2
class ShapeExtra
{
public ShapeExtra() {}
}
class CircleExtra : ExtraClass
{
public CircleExtra() {}
void CircleExtraFunc() {//Do stuff}
}
class TriangleExtra : ExtraClass
{
public TriangleExtra() {}
void TriangleExtra() {//Do stuff}
}
.
.
.
So, I need the m_var in the child classes to be kept it as its own unique version. Because right now (w/o the extra CircleExtra m_var;), the GetVar() works, but in CircleFunc, m_var is still type of ShapeExtra, and thus doesn't know that CircleExtraFunc exists. I could cast m_var each time I wanted to do that, but that is repetitive and not worth it in my real-world case. Is there a way to utilize the functions in unique classes based off of ShapeExtra, while keeping the GetVar() function in Shape?
Please ask questions if there is anything I left out.
Simply with inheritance and without using pointers it is not possible, as C++ is a statically-and-strictly-typed language.
You can inherit both the variable and the function, but you'll need to cast function return value.
You can also override the function to make it return the concrete type, but then you have to cast the variable inside the function.
You can also declare the same var with the concrete class in subclasses, but then you just hide the variable in the superclass and inherit nothing.
I'd rather go for a solution using templates. Make the type of the variable a template type and extend the template using a concrete type in subclasses. It'll work perfectly.
It's been a long time since I last programmed in C++ and I beg your pardon if there are errors in the following example. I'm sure you can easily make it work.
template <class S>
class Shape {
S m_var;
//......
public:
S var () {
return m_var;
}
//.......
}
class Circle: Shape <CircleExtra> {
// var method returns CircleExtra
//......
}
Edit:
Regarding some comment, to allow virtual invocation of the method, it is possible to use correlated return types. Something like the following example.
class Shape {
public:
virtual ShapeExtra *var () = 0;
}
template <typename SE>
class ConcreteShape: Shape {
public:
virtual SE *var() {
return &m_var;
}
// Constructor, etc.
private:
SE m_var;
}
Or some variation. Now concrete shapes can benefit from extending the template, as long as SE * is correlated with ShapeExtra * (the type parameter extends ShapeExtra). And you can vall the method transparently through Shape interface.
Using pointers, this is totally possible.
Using your example, you could do something like this:
#include <iostream>
#include <memory>
using namespace std;
//Extras
class ShapeExtra
{
public:
ShapeExtra() {}
void ShapeFunc() { std::cout << "Shape"; }
virtual ~ShapeExtra() = default; //Important!
};
class Shape
{
public:
std::unique_ptr<ShapeExtra> m_var;
//require a pointer on construction
//make sure to document, that Shape class takes ownership and handles deletion
Shape(ShapeExtra* p):m_var(p){}
//The common functions
ShapeExtra& GetVar(){ return *m_var; }
void ShapeFunc() {m_var->ShapeFunc();}
};
class CircleExtra : public ShapeExtra
{
public:
void CircleExtraFunc() {std::cout << "Circle";}
};
class Circle : public Shape
{
CircleExtra* m_var;
public:
Circle() : Shape(new CircleExtra()) {
m_var = static_cast<CircleExtra*>(Shape::m_var.get());
}
void CircleFunc()
{
m_var->CircleExtraFunc();
}
};
int main() {
Circle c;
//use the ShapeExtra Object
c.GetVar().ShapeFunc();
//call via forwarded function
c.ShapeFunc();
//call the circleExtra Function
c.CircleFunc();
return 0;
}
Test it on ideone
Note the use of pointers and a virtual destructor:
By using a virtual destructor in the ShapeExtra base class, you make it possible to destruct an object of any derived class, using a ShapeExtra*. This is important, because
by using a std::unique_ptr<ShapeExtra> instead of a plain C-pointer, we make sure that the object is properly deleted on destruction of Shape.
It is probably a good idea to document this behaviour, i.e. that Shape takes the ownership of the ShapeExtra*. Which especially means, that we do not delete CirleExtra* in the Circle destructor
I decided here to require the ShapeExtra* on construction, but its also possible to just use std::unique_ptr::reset() later and check for nullptr on dereferencing Shape::m_var
Construction order is this: On calling the constructor of Circle, we first create a new CircleExtra which we pass to Shape before finally the constructor of Circle is executed.
Destruction order is Circle first (was created last), then Shape which also destructs the ShapeExtra for us, including (via virtual function) the CircleExtra
I would recommend the following approach:
class ShapeExtra
{
public:
virtual ~ShapeExtra() { }
virtual void SomeCommonShapeFunc() { std::cout << "Shape"; }
};
class Shape
{
public:
virtual ShapeExtra &GetVar() = 0; // Accessor function.
};
Note that the class Shape does not have any data members at all. After that for each derived class you need:
class CircleExtra : public ShapeExtra
{
public:
void SomeCommonShapeFunc() { std::cout << "Circle"; }
};
class Circle : public Shape
{
CircleExtra m_var; // Data member with circle specific class.
public:
virtual ShapeExtra &GetVar() { return m_var; }
};
Implementation of virtual method in Circle will return reference to the base class ShapeExtra. This will allow using this extra in the base class.
Note that pointers and templates are not used at all. This simplifies the overall design.

oop - C++ - Proper way to implement type-specific behavior?

Let's say I have a parent class, Arbitrary, and two child classes, Foo and Bar. I'm trying to implement a function to insert any Arbitrary object into a database, however, since the child classes contain data specific to those classes, I need to perform slightly different operations depending on the type.
Coming into C++ from Java/C#, my first instinct was to have a function that takes the parent as the parameter use something like instanceof and some if statements to handle child-class-specific behavior.
Pseudocode:
void someClass(Arbitrary obj){
obj.doSomething(); //a member function from the parent class
//more operations based on parent class
if(obj instanceof Foo){
//do Foo specific stuff
}
if(obj instanceof Bar){
//do Bar specific stuff
}
}
However, after looking into how to implement this in C++, the general consensus seemed to be that this is poor design.
If you have to use instanceof, there is, in most cases, something wrong with your design. – mslot
I considered the possibility of overloading the function with each type, but that would seemingly lead to code duplication. And, I would still end up needing to handle the child-specific behavior in the parent class, so that wouldn't solve the problem anyway.
So, my question is, what's the better way of performing operations that where all parent and child classes should be accepted as input, but in which behavior is dictated by the object type?
First, you want to take your Arbitrary by pointer or reference, otherwise you will slice off the derived class. Next, sounds like a case of a virtual method.
void someClass(Arbitrary* obj) {
obj->insertIntoDB();
}
where:
class Arbitrary {
public:
virtual ~Arbitrary();
virtual void insertIntoDB() = 0;
};
So that the subclasses can provide specific overrides:
class Foo : public Arbitrary {
public:
void insertIntoDB() override
// ^^^ if C++11
{
// do Foo-specific insertion here
}
};
Now there might be some common functionality in this insertion between Foo and Bar... so you should put that as a protected method in Arbitrary. protected so that both Foo and Bar have access to it but someClass() doesn't.
In my opinion, if at any place you need to write
if( is_instance_of(Derived1) )
//do something
else if ( is_instance_of(Derived2) )
//do somthing else
...
then it's as sign of bad design. First and most straight forward issue is that of "Maintainence". You have to take care in case further derivation happens. However, sometimes it's necessary. for e.g if your all classes are part of some library. In other cases you should avoid this coding as far as possible.
Most often you can remove the need to check for specific instance by introducing some new classes in the hierarchy. For e.g :-
class BankAccount {};
class SavingAccount : public BankAccount { void creditInterest(); };
class CheckingAccount : public BankAccount { void creditInterest(): };
In this case, there seems to be a need for if/else statement to check for actual object as there is no corresponsing creditInterest() in BanAccount class. However, indroducing a new class could obviate the need for that checking.
class BankAccount {};
class InterestBearingAccount : public BankAccount { void creditInterest(): } {};
class SavingAccount : public InterestBearingAccount { void creditInterest(): };
class CheckingAccount : public InterestBearingAccount { void creditInterest(): };
The issue here is that this will arguably violate SOLID design principles, given that any extension in the number of mapped classes would require new branches in the if statement, otherwise the existing dispatch method will fail (it won't work with any subclass, just those it knows about).
What you are describing looks well suited to inheritance polymorphicism - each of Arbitrary (base), Foo and Bar can take on the concerns of its own fields.
There is likely to be some common database plumbing which can be DRY'd up the base method.
class Arbitrary { // Your base class
protected:
virtual void mapFields(DbCommand& dbCommand) {
// Map the base fields here
}
public:
void saveToDatabase() { // External caller invokes this on any subclass
openConnection();
DbCommand& command = createDbCommand();
mapFields(command); // Polymorphic call
executeDbTransaction(command);
}
}
class Foo : public Arbitrary {
protected: // Hide implementation external parties
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Foo specific fields here
}
}
class Bar : public Arbitrary {
protected:
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Bar specific fields here
}
}
If the base class, Arbitrary itself cannot exist in isolation, it should also be marked as abstract.
As StuartLC pointed out, the current design violates the SOLID principles. However, both his answer and Barry's answer has strong coupling with the database, which I do not like (should Arbitrary really need to know about the database?). I would suggest that you make some additional abstraction, and make the database operations independent of the the data types.
One possible implementation may be like:
class Arbitrary {
public:
virtual std::string serialize();
static Arbitrary* deserialize();
};
Your database-related would be like (please notice that the parameter form Arbitrary obj is wrong and can truncate the object):
void someMethod(const Arbitrary& obj)
{
// ...
db.insert(obj.serialize());
}
You can retrieve the string from the database later and deserialize into a suitable object.
So, my question is, what's the better way of performing operations
that where all parent and child classes should be accepted as input,
but in which behavior is dictated by the object type?
You can use Visitor pattern.
#include <iostream>
using namespace std;
class Arbitrary;
class Foo;
class Bar;
class ArbitraryVisitor
{
public:
virtual void visitParent(Arbitrary& m) {};
virtual void visitFoo(Foo& vm) {};
virtual void visitBar(Bar& vm) {};
};
class Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Parent specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitParent(*this);
}
};
class Foo: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Foo specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitFoo(*this);
}
};
class Bar: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Bar specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitBar(*this);
}
};
class SetArbitaryVisitor : public ArbitraryVisitor
{
void visitParent(Arbitrary& vm)
{
vm.DoSomething();
}
void visitFoo(Foo& vm)
{
vm.DoSomething();
}
void visitBar(Bar& vm)
{
vm.DoSomething();
}
};
int main()
{
Arbitrary *arb = new Foo();
SetArbitaryVisitor scv;
arb->accept(scv);
}

using directive and abstract method

I have a class (let's call it A) the inherits an interface defining several abstract methods and another class there to factor in some code (let's call it B).
The question is, I have an abstract method in the interface that A implements just to call the B version. Is there a way to use the keyword using to avoid writing a dull method like:
int A::method() override
{
return B::method();
}
I tried writing in A using B::method, but I still get an error that A doesn't implement the abstract method from the interface.
Is there a special technique to use in the case or am I just out of luck? (and if so, is there a specific reason why it should be that way?).
Thanks.
edit:
To clarify, the question is, why isn't it possible to just do this:
class A: public Interface, public B {
using B::method;
};
Let's make this clear. You basically have the following problem, right?
struct Interface
{
virtual void method() = 0;
};
struct B
{
void method()
{
// implementation of Interface::method
}
};
struct A : Interface, B
{
// some magic here to automatically
// override Interface::method and
// call B::method
};
This is simply impossible, because the fact that the methods have the same names is irrelevant from a technical point view. In other word's, Interface::method and B::method are simply not related to each other, and their identical names are not more than a coincidence, just like someone else called "Julien" doesn't have anything to do with you just because you share the same first name.
You are basically left with the following options:
1.) Just write the call manually:
struct A : Interface, B
{
virtual void method()
{
B::method();
}
};
2.) Minimise writing work with a macro, so that you can write:
struct A : Interface, B
{
OVERRIDE(method)
};
But I would strongly recommend against this solution. Less writing work for you = more reading work for everyone else.
3.) Change the class hierarchy, so that B implements Interface:
struct Interface
{
virtual void method() = 0;
};
struct B : Interface
{
virtual void method()
{
// implementation of Interface::method
}
};
struct A : B
{
};
if B::method is abstract you cannot call it because is not implemented... has no code.
An example:
class A
{
public:
virtual void method1( ) = 0;
virtual void method2( ){ }
};
class B : public A
{
public:
virtual void method1( ) override
{ return A::method1( ); } // Error. A::method1 is abstract
virtual method2( ) override
{ return A::method2( ); } // OK. A::method2 is an implemented method
}
Even if there were a way to do what you want, in the name of the readability of your code, I would not recommend that.
If you do not put the "B::" before "method" call, when I read that, I would say it is a recursive call.

How to call a function from a derived class in a base class?

I spent hours and hours looking online but none had the same problem as me. Basically, I have a base class called MainShop and it has 3 derived classes which are SwordShop, SpellBookShop and BowShop. I want the base class to be able to call a function from one of the derived classes but no matter what i do, it doesn't seem to work!
Here is my code:
#include "MainShop.h"
//BaseClass cpp
void MainShop::EnterShop(Hero& hero)
{
//Display Choices
switch (choice)
{
//Swords
case 1: SwordShop::soldierShop(hero);//DOES NOT WORK!!
break;
case 2: SpellBookShop::MageShop(hero);//Staffs
break;
case 3: BowShop::ArcherShop(hero);//Bows
break;
default: cout << "Error!, Please try again.";
MainShop::EnterShop(hero);
}
}
I have two other derived classes, but its basically the same concept. I have a function in one of the derived classes and i would like to call it from the base class. This is one my derived classes:
//SwordShop derived cpp
#include "SwordShop.h"
void SwordShop::soldierShop(Hero& hero)
{
/* some code here*/
}
It's not a good design to select specific sub-class instance in super-class methods, e.g., by dynamic_cast, due to runtime overhead, and future maintenance, etc.
You can offload the burden of such switch-case logic to virtual functions which are designed by the language to call a specific instance via base class pointer/reference.
For example:
class MainShop
{
public:
virtual void EnterShop(Hero &hero) = 0;
};
class SwordShop: public MainShop
{
void EnterShop(Hero &hero)
{
soldierShop(hero);
}
};
class SpellBookShop: public MainShop
{
void EnterShop(Hero &hero)
{
MageShop(hero);
}
};
int main()
{
...
MainShop *shop = new SwordShop;
// calling soldierShop
shop->EnterShop(hero);
..
shop = new SpellBookShop;
// calling MageShop
shop->EnterShop(hero);
...
}
I guess you could try something like:
Derived* derived = dynamic_cast<Derived*>(this);
if (derived) {
// this is of Derived type
} else {
// this is of base type but not Derived
}
though as suggested you'd better use virtual function, since its the right use case:
class Base {
public:
virtual void someMethod() = 0;
void anotherMethods() {
someMethod(); // determined by implementation in derived class
}
};
class Derived1 : public Base {
virtual void someMethod() override {
// body
}
};
class Derived2 : public Base {
virtual void someMethod() override {
// body
}
};
Better readability, less error prone, much more sane.
If you need to call EnterShop from any shop object (SwordShop etc.) then overriding a virtual function in the base class is the way to go.
class MainShop
{
...
virtual void process_hero(Hero& hero)
{
// add default implementation or set as pure virtual
}
...
};
void MainShop::EnterShop(Hero& hero)
{
process_hero(hero);
}
class SwordShop: public MainShop
{
public:
void process_hero(hero)
{
soldierShop(hero);
}
};
...
However, it looks to me like you want a manager object to invoke the functions depending on the 'choice' variable. If this is the case, use composition instead of inheritance.
Prefer composition over inheritance?
How about something like this?
Obviously you must implement the .shop() function:
MainShop *ms;
switch(input){
case 1:
ms = new soldierShop(); break;
case 2:
ms = new MageShop(); break
case 3:
ms = new ArcherShop(); break;
}
ms.shop();
There are 2 options usually used to achieve the required functionality:
use dynamic_cast<> to promote this pointer to the desired derived type and call whatever you want if cast succeeds.
use templated base class in conjunction with curiously recurring template pattern - basically, pass the desired derived type as template argument to base class (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).