Seeing what class an object is - c++

If I have a pointer to a base class A in C++, how would I be able to tell in my code that the pointer is to a derived class B or C?

Assuming the base class A is polymorphic (i.e. it has at least one virtual function), you can use dynamic_cast. Given an A* ap;:
if (B* bp = dynamic_cast<B*>(ap)) {
// the object is a B
}
else if (C* cp = dynamic_cast<C*>(ap)) {
// the object is a C
}

You generally shouldn't need to know:
struct A {
virtual int generate_foo() = 0;
};
struct B : A {
int generate_foo() { return 42; }
};
struct C : A {
i_;
C(int i) : i_(i) { }
int generate_foo() { return i_++; }
};
If you have an A* you (1) know that it has a generate_foo() method, and (2) know that generate_foo() will generate an appropriate foo for whatever object you really do have. In general that should be enough and you should be able to keep track of when you have an A*.
Philosophically, the designers of C++ spent years trying to avoid adding runtime type information because it' too easily used incorrectly. However, they eventually decided that they were on the wrong end of a losing battle and added dynamic_cast and typeinfo(). C++0x will add more.

Related

Number of vtable that will be created

Here if I leave class B as empty then total how many vtables will be created here ?
#include <bits/stdc++.h>
using namespace std;
class A{
public:
virtual void display(){
cout<<"A Class"<<endl;
}
};
class B: public A{
public:
};
int main()
{
A *ob = new B();
ob->display();//A Class
return 0;
}
I was assuming still 2 vtable will be created one in A and 1 in B but for Class B it will be empty and as per design of c++ if we call display function then if it doesn't find the function in its vtable then it will look for the vtable in parent class and will set the binding of that function with vptr but, I am not sure of that.
Can anybody explain with the exact concept
I tired finding the answer over the internet but, didn't get the desired answer
Practically B needs some run time type information, which is typically stored as part of the "vtable" , that is distinct from A.
This is because:
bool test(A* a) {
return dynamic_cast<B*>(a);
}
has to behave differently if we pass a pointer-to-B or a pointer-to-A.
A "typical" way to implement vtables in C++ looks like this:
using vfunc = void(*)(void*);
template<auto creator>
static auto const* get_vtable() {
static const auto table = creator();
return &table;
}
struct A_vtable {
void const* rtti;
void(*display)(void*);
};
A_vtable create_A_vtable_A() {
return {
"This is class A!",
[](void* self) {
std::cout<<"A Class"<<std::endl;
}
};
}
struct A {
A_vtable const* vtable;
A():vtable(get_vtable<&create_A_vtable_A>()) {}
};
struct B_vtable:A_vtable {
};
B_vtable create_B_vtable_B() {
B_vtable vtable = create_A_vtable_A;
vtable.rtti = "This is class B!";
}
struct B:A {
B() {
vtable = get_vtable<&create_B_vtable_B>();
}
};
with the note that my runtime type information is intentionally a joke.
That RTTI information in a real situation will tell you how what the runtime type is, and how to get a pointer to the most-derived type. Here I just store a void pointer to a string.
But you'll notice I moved the vtable pointer to a different table in the constructor of B. This is basically how compilers do it (the standard gives compilers lots of freedom, so you cannot assume it looks anything at all like the above, it might not even have a vtable).

Check intermediate ancestor type of object

Some places in our code make extensive use of 'dynamic_cast` do check the type of a given object:
if (dynamic_cast<Foo*>(bar))
return "foo";
else
return "not-foo";
In some specific section of the code, we decided to switch to typeid, but we ran into a problem: we're checking an object against an arbitrary ancestor, not to its concrete type:
#include <typeinfo>
#include <iostream>
struct Base
{
virtual ~Base() {} // enable vtable
};
struct Derived : Base{};
struct DerivedAgain : Derived{};
struct OtherDerived : Derived{};
int main() {
Base* b = new DerivedAgain;
// if (typeid(*b) == typeid(Derived)) // will print false
if (dynamic_cast<Derived*>(b))
std::cout << "true\n";
else
std::cout << "false\n";
return 0;
}
Is there a way to check if b is Derived* without dynamic_cast?
P.S.: I'm aware this might be indicative of some larger problem with the design of the code, but I want to know specifically how to make this kind of check.
A quick way to go around dynamic_cast, with some manual work, if you have relatively few types:
add a static constexpr/const int mytypeno member to each class with a distinct prime number (this can be done automatically)
add another static constexpr/const int mytypecompatibility member, which is:
for base (topmost classes) the same as mytypeno
for classes that has base classes, the product of their mytypeno and all base classes' mytypeno
Then you can check if a class is a descendant of another as: descendant.mytypecompatibility % base.mytypeno == 0. This idea was originally proposed by Bjarne for a quick implementation of dynamic_cast<> with full access to all sources (vs. local solutions). It's also relatively little intrusion as you only take two static constexpr members, thus no per-object overhead and you don't force virtual table to be used.
It seems that dynamic_cast is what I want in this specific case, since it is the only thing in the language that will actually examine the dependency chain of the object.
That said, it's worth mentioning that, as I said in the question and many people said in the comments, having to use dynamic_cast may be an indicative of a larger design problem in the code. One possible solution is using a polymorphic method instead:
// with checking
int doThing(Base* b)
{
if (auto d = dynamic_cast<Derived*>(b))
return stuff(d);
if (auto d = dynamic_cast<OtherDerived*>(b))
return otherStuff(d);
return 0;
}
// with polymorphism
int doThing(Base* b)
{
return b->stuff();
}
// stuff is a virtual method defined in Base, Derived and OtherDerived
struct Base
{
virtual int stuff() const {}
};
struct Derived : Base
{
int stuff() const override { return stuff(this); }
};
struct OtherDerived : Base
{
int stuff() const override { return otherStuff(this); }
};

Grouping two types together

I use a third party library over which I have no control. It contains 2 classes A and B, which both define a method with the same name:
class A {
public:
...
void my_method ();
};
class B {
public:
...
void my_method ();
};
I want to create a class C that contains a member which is of class A or B. Crucially, I can know only at runtime whether I will need A or B. This class C will only call the method my_method.
If I could modify the code, I would simply make A and B derive from a parent class (interface) that defined my_method. But I can't.
What is the simplest/most elegant way to create this class C? I could of course define C in this way:
class C {
public:
void call_my_method() { if (a) a->my_method() else b->my_method(); }
private:
A* a;
B* b;
But I want to avoid paying the cost of the if statement everytime. It also feels inelegant. Is there a way I can create a super type of class A or B? Or any other solution to this problem?
You may use std::function (not sure it has better performance though), something like:
class C {
public:
void call_my_method() { my_method(); }
void use_a(A* a) { my_method = [=]() { a->my_method() }; }
void use_b(B* b) { my_method = [=]() { b->my_method() }; }
private:
std::function<void()> my_method;
};
No; at some point you need branching. The best you can do is to hoist the branching up/down the call stack†, so that more of your program is encapsulated within the figurative if/else construct and the branch itself need be performed less frequently. Of course then you need to duplicate more of your program's source code, which is not ideal.
The only improvement I'd suggest at this time is a construct such as boost::variant. It basically does what you're already doing, but takes up less memory and doesn't have that layer of indirection (using what's called a tagged union instead). It still needs to branch on access, but until profiling has revealed that this is a big bottleneck (and you'll probably find that branch prediction alleviates much of this risk) I wouldn't go any further with your changes.&ddagger;
† I can never remember which way it goes lol
&ddagger; One such change might be to conditionally initialise a function pointer (or modern std::function), then call the function each time. However, that's a lot of indirection. You should profile, but I'd expect it to be slower and harder on the caches. An OO purist might recommend a polymorphic inheritance tree and virtual dispatch, but that's not going to be of any use to you once you care about performance this much.
How about using inheritance with a virtual function, using a 'base class' (C):
class C
{
public:
virtual void do_method() = 0;
};
class D : public C, private A
{
void do_method() { my_method(); }
};
class E : public C, private B
{
void do_method() { my_method(); }
}
Then this will work:
C * d = new D();
d->do_method();
Suggest to wrap your A and B objects into some helper template TProxy which realizes IProxy interface. Class C (or Consumer) will work with IProxy interface and won't know about type of the object inside Proxy
#include <stdio.h>
struct A {
void func () { printf("A::func\n"); }
};
struct B {
void func () { printf("B::func\n"); }
};
struct IProxy
{
virtual void doFunc() = 0;
virtual ~IProxy() {};
};
template<typename T>
struct TProxy : public IProxy
{
TProxy(T& i_obj) : m_obj(i_obj) { }
virtual void doFunc() override { m_obj.func(); }
private:
T& m_obj;
};
class Consumer
{
public:
Consumer(IProxy& i_proxy) : m_proxy(i_proxy) {}
void Func() { m_proxy.doFunc();}
private:
IProxy& m_proxy;
};
Main:
int main()
{
A a;
TProxy<A> aProxy(a);
B b;
TProxy<B> bProxy(b);
Consumer consumerA{aProxy};
consumerA.Func();
Consumer consumerB{bProxy};
consumerB.Func();
return 0;
}
Output:
A::func
B::func

Pointer to a Class Type

Essentially I'm trying to work around the problem of not being able to store derived types as a derived type in a (value) array of a base type. I have multiple classes that store one to three ints but have to have very different sets of functions. I'd use an array of pointers but the entire array is traversed forwards, then backwards constantly, mostly linearly, so keeping it all together in memory is preferable. I could create multiple arrays, one for each type and then an array of pointers to each of those, but that would get pretty clumsy fast and really wouldn't be the same as each element packed neatly between the one preceding it and the one proceeding it in order of access at runtime.
So what I'm thinking is that I make a POD struct with three ints and a pointer and fill an array with those, then use that pointer to access polymorphic functions. It would end up something along these lines: (forgive the poor coding here, I'm just trying to convey the concept)
class A {
int aa( &foo f ) { return 1; }
int dd() { return 9; }
};
class B : A {
int aa( &foo f ) { return f.b; }
};
class C : A {
int aa( &foo f ) { return cc() + f.c - f.a; }
int cc() { return 4; }
};
class D : B {
int dd() { return 7; }
};
struct foo{ int a, b, c; A* ptr; };
const A AA = A(); const B BB = B(); const C CC = C(); const D DD = D();
foo[100] foos;
init() {
foo[0] = foo{ 1, 2, 3, &BB };
// etc fill foos with various foo elements
}
bar(){
for ( int i = 0; i < 100; ++i ){
print foos[i].ptr.aa( &foos[i] );
print foos[i].ptr.dd();
}
}
main(){
init();
while(true)
bar();
}
I'm just wondering if this is the best way to go about what I want to achieve or if there's a better solution? Ideally I'd just point to a class rather than an instance of a class but I don't think I can really do that... ideally I'd store them in an array as multiple derived types but for obvious reasons that's not going to fly.
What you are looking for are virtual functions.
In the bellow example :
class A
{
virtual void foo(){printf("A is called");};
}
class B : public A
{
void foo(){printf("B is called");};
}
...
A* ptr = new B();
ptr->foo();
Will produce "B is called" .
If you don't want to use virtual functions (to save memory for example), you can use dynamic cast , but this will lead to significant performance loss.
Please not that you need to have at least 1 virtual function to perform dynamic cast.
In the example bellow :
class A {...}
class B : public A {...}
class C : public A {...}
A* ptr1 = new C();
B* ptr2 = dynamic_cast<B*>(ptr1);
C* ptr3 = dynamic_cast<C*>(ptr1);
ptr2 will be null, and ptr3 will have a value.
So you can make the following (very wrong) construct :
if (ptr2)
{
ptr2->bb();
} else if (ptr3)
{
ptr3->cc();
}
Finally, you can get rid of dynamic casting by having your own typing mechanism and then just C cast to the correct class.
You need polymorphism. In your example all the classes have standard methods. You need to make them virtual, so the polymorphism can be applied.
class A {
virtual int aa( foo& f )const { return 1; }
virtual int dd()const { return 9; }
};
class B : A {
virtual int aa( foo& f )const { return f.b; }
};
class C : A {
virtual int aa( foo& f )const { return cc() + f.c - f.a; }
int cc()const { return 4; }// this doesn't need to be virtual because is not in the base class A
};
class D : B {
virtual int dd()const { return 7; }
};
Here is some information on this topic: http://www.cplusplus.com/doc/tutorial/polymorphism/. There is some information on how to use pointers as well.
I would suggest to look at smart pointers: http://www.cplusplus.com/reference/memory/shared_ptr/?kw=shared_ptr
Another topic you should look at is constness: search for "constness c++" (cannot post more then 2 links)
struct foo{ int a, b, c;const A* ptr; }; // const A* instead of A*
... I'm trying to work around the problem of not being able to store derived types as a derived type in a (value) array of a base type.
You can store derived types, as values, in an array - you just can't store them as instances of the base type.
A union of your concrete leaf types is almost what you want, but there's no way to figure out which member of the union is live, or to use polymorphic dispatch.
A discriminated union is one which tells you which member is live, but doesn't directly help with the dispatch.
Boost.Variant is a specific discriminated union which provides a clean mechanism for polymorphic dispatch - not using virtual, but using a visitor with overloads for each concrete stored type. In this case, you don't even need the stored types to be related to a common abstract base - they can be entirely unrelated. Look for apply_visitor in the tutorial for details.

One pointer, two different classes in c++

Suppose I have two structures a and b, each hold several variable in them (most of the variable are c++ core types but not all).
Is there a way to create a a pointer named c that can point to either one of them? Alternatively, is there a way to create a set that can hold either one of them?
Thanks
The usual way to create a pointer that can point to either of the two is to make them inherit from a common base-class. Any pointer of the base-class can point to any sub-class. Note that this way you can only access elements that are part of the base-class through that pointer:
class Base {
public:
int a;
};
class Sub1 : public Base {
public:
int b;
};
class Sub2 : public Base {
public:
int c;
};
int main() {
Base* p = new Sub1;
p.a = 1; // legal
p.b = 1; // illegal, cannot access members of sub-class
p = new Sub2; // can point to any subclass
}
What you are trying to achieve is called polymorphism, and it is one of the fundamental concepts of object oriented programming. One way to access member of the subclass is to downcast the pointer. When you do this, you have to make sure that you cast it to the correct type:
static_cast<Sub1*>(p).b = 1; // legal, p actually points to a Sub1
static_cast<Sub2*>(p).c = 1; // illegal, p actually points to a Sub1
As for your second question, using the technique described above, you can create a set of pointers to a base-class which can then hold instance of any of the subclasses (these can also be mixed):
std::set<Base*> base_set;
base_set.insert(new Sub1);
base_set.insert(new Sub2);
Alternatively, is there a way to create a set that can hold either one
of them?
Take a look at Boost.Any and Boost.Variant. If you have just 2 classes, then variant should suffice. If you plan other types, and don't want to recompile this 'set', then use any.
Then use any container of either any or variant.
#include <boost/any.hpp>
#include <boost/variant.hpp>
#include <vector>
class A { };
class B { };
class C { };
int main()
{
// any
std::vector<boost::any> anies;
anies.push_back(A());
anies.push_back(B());
A a0 = boost::any_cast<A>(anies[0]);
A b0 = boost::any_cast<A>(anies[1]); // throws boost::bad_any_cast
// variant
std::vector<boost::variant<A,B> > vars;
vars.push_back(A());
vars.push_back(B());
A a1 = boost::get<A>(vars[0]);
A b1 = boost::get<A>(vars[1]); // throws boost::bad_get
// and here is the main difference:
anies.push_back(C()); // OK
vars.push_back(C()); // compile error
}
Edit: having more than 2 classes is of course possible for variant, too. But extending variant so it is able to hold a new unanticipated type without recompilation is not.
If a and b are unrelated, then you can use a void* or, better, a boost any type.
If a is superclass of b, you can use an a* instead.
If they both inherit from the same type you can do it. Thats how OOP frameworks work, having all classes inherit from Object.
Although you can do that, what would that pointer mean? If any portion of your application gets hold on the pointer to 'either a or b', it cannot do a lot with it, unless you provide extra type information.
Providing extra type information will result in client code like
if( p->type == 'a' ) {
... a-specific stuff
} else if( p->type == 'b' ) {
... b-specific stuff
} ...
Which isn't very useful.
It would be better to delegate 'type-specificness' to the object itself, which is the nature of object-oriented design, and C++ has a very good type-system for that.
class Interface {
public:
virtual void doClientStuff() = 0; //
virtual ~theInterface(){};
};
class A : public Interface {
virtual void doClientStuff(){ ... a-specific stuff }
};
class B : public Interface {
virtual void doClientStuff(){ ... b-specific stuff }
};
And then your client code will become more type-unaware, since the type-switching is done by C++ for you.
void clientCode( Interface* anObject ) {
anObject->doClientStuff();
}
Interface* i = new A();
Interface* j = new B();
clientCode( i );
clientCOde( j );
There are several ways to do this:
Using the more generic base type, if there is an inheritance relationship.
Using void* and explicitly casting where appropriate.
Creating a wrapper class with the inheritance relationship needed for #1.
Using a discriminating container via union.
Since others have already described the first three options, I will describe the fourth. Basically, a discriminated container uses a union type to use the storage of a single object for storing one of multiple different values. Typically such a union is stored in a struct along with an enum or integral type for distinguishing which value is currently held in the union type. As an example:
// Declarations ...
class FirstType;
class SecondType;
union PointerToFirstOrSecond {
FirstType* firstptr;
SecondType* secondptr;
};
enum FIRST_OR_SECOND_TYPE {
FIRST_TYPE,
SECOND_TYPE
};
struct PointerToFirstOrSecondContainer {
PointerToFirstOrSecond pointer;
FIRST_OR_SECOND_TYPE which;
};
// Example usage...
void OperateOnPointer(PointerToFirstOrSecondContainer container) {
if (container.which == FIRST_TYPE) {
DoSomethingWith(container.pointer.firstptr);
} else {
DoSomethingElseWith(container.pointer.secondptr);
}
}
Note that in the code below, "firstptr" and "secondptr" are actually two different views of the same variable (i.e. the same memory location), because unions share space for their content.
Note that even though this is a possible solution, I seriously wouldn't recommend it. This kind of thing isn't very maintainable. I strongly recommend using inheritance for this if at all possible.
Just define a common superclass C and two subclasses A, B of C. If A and B have no common structure (no common attributes), you can leave C empty.
The define:
A *a = new A();
B *b = new B();
C *c;
Then you can do both
c = a;
or
c = b;
Abstract Class !!!! -- simple solutions
To have a base class that can be used as a pointer to several derived sub classes. (no casting needed)
Abstract class is define when you utilize a virtual method in it. Then you implement this method in the sub-class... simple:
// abstract base class
#include <iostream>
using namespace std;
class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) =0;
};
class Rectangle: public Polygon {
public:
int area (void)
{ return (width * height); }
};
class Triangle: public Polygon {
public:
int area (void)
{ return (width * height / 2); }
};
int main () {
Polygon * ppoly1 = new Rectangle (4,5);
Polygon * ppoly2 = new Triangle (4,5);
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << '\n';
cout << ppoly2->area() << '\n';
return 0;
}