C++: Determining derived type from a base type pointer
NickName:Casey Ask DateTime:2013-11-05T13:41:43

C++: Determining derived type from a base type pointer

Background:

See this question in the C++ FAQ for a similar situation that I need to solve, but with named constructors.

I have a Base class, class B.

I have a Derived class from B, class D, that adds additional functionality via functions, members, and additional memory allocation.

The additional functionality is polymorphically supported in class B by doing nothing or returning default values and nullptrs from the virtual functions specific to class D.

class B uses public static Factory Methods for construction with all protected constructors. (see: Named Constructor Idiom)

class D uses public static Factory Methods for construction with all protected constructors that are named differently from class B and not available in class B.

Sometime later, a new interface class is created, class A. This class has an interface such that the derived classes from class A must have a getter function and a setter function that both require a pointer to a class B but the dynamic value can be either class B or class D

Question:

I want to derive class A and create a copy constructor, an assignment operator, and/or a setter for class B but because class A only exposes its member(s) as an object of type B I have no way of determining if the object returned is class B or class D.

How would I correctly implement the above using only the public interface without causing slicing or memory issues (including if the above is set up wrong and needs to be changed)?

Possible solutions?:

I'm tempted to try a couple of options:

1) Create a member in class B and all derived types that declares the type of object:

if(getB()->GetType() == "D") {
    //Call D::CreateD(...)
} else if(getB()->GetType() == "B") {
    //Call B::CreateB(...)
}

2) Dynamically cast to the derived type and check for failure:

if(dynamic_cast<D*>(getB()) == nullptr) {
    //Call B::CreateB(...)
} else {
    //Call D::CreateD(...)
}

3) Use a virtual method that is specific to class D that I know returns nullptr when used on a class B object:

if(getB()->VirtualMethodSpecificToClassD() == nullptr) {
    //Call B::CreateB(...)
} else {
    //Call D::CreateD(...)
}

All three cases have code smells:

  1. Causes "else-if-heimers".
  2. Not too sure this will actually work.
  3. Violates the good practice of "code to interfaces not implementations".

Copyright Notice:Content Author:「Casey」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/19782588/c-determining-derived-type-from-a-base-type-pointer

More about “C++: Determining derived type from a base type pointer” related questions

Is there any difference between C c; and C c = C();?

#include&lt;iostream&gt; using namespace std; class C{ private: int value; public: C(){ value = 0; cout&lt;&lt;"default constructor"&lt;&lt;endl; }

Show Detail

Rebinding C-c to C-c

I'm using Viper, and I want to change its C-c and C-g to the original emacs functions. I can rebind C-g with (define-key viper-vi-global-user-map "C-g" 'keyboard-quit), but how can I rebind C-c, si...

Show Detail

Why value of variable c in (c=c==c) is 2 instead of 1,in C programming?

#include&lt;stdio.h&gt; int main() { int a=10,b=2,c; a=!++b&amp;&amp;(c=c==c); printf("b value is %d \n",b); printf("c value is %d \n",c);

Show Detail

The difference between "C c = new C()" and "A c = new C()" when C is a subclass of A in Java

Let's say we have class A as a parent class, and class C that extends it. class A { void m() { System.out.println("A.m"); } } class C extends A { @Override v

Show Detail

Mounting of /cygdrive/c resolves to C:\cygdrive\c

I am using Cygwin and try to run a bash script which uses the pwd command to construct a path and then generate a directory. The problem is that the directory is created under c:\cygdrive\c rather ...

Show Detail

Prefix key `C-S-c` is echoed as `C-c`

When I press C-S-c, the echo area shows only C-c. Things like C-S- selection do work, however. I'm in Ubuntu 14.10 Utopic Unicorn in case this helps. Here's the code for the key binding (for mul...

Show Detail

What is the difference between C, C99, ANSI C and GNU C?

I have started programming practice on codechef and have been confused by the difference between C and C99. What does C mean here? Is it C89? Check the languages at the bottom of this submit. It co...

Show Detail

Is C# a superset of C?

Is C# a superset of C in anyway, like Objective-C or C++? Is there a way to compile C online with constructs such compiler flags?

Show Detail

C - Scope of C Functions

I apologize if this is a beginner's question, but after working in C for a bit, I finally would like a bit of clarification on exactly what kind of files/functions are available to a function. I

Show Detail

Why a != b != c is not equal to a != b and a != c and b != c?

I want to check if 3 values a, b , c are not equal to each other. Given that a == b == c equals to a == b and b == c and a == c, why does python give a different answer for a != b != c ? Thanks! ...

Show Detail