Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have 2 classes:
#include <iostream>
using namespace std;
class A
{
public:
virtual void print()=0;
};
class B: public A
{
public:
void print()
{
cout<<"B\n";
}
void printNew()
{
cout<<"Print new";
}
};
int main()
{
B b;
A *a=new B;
a->printNew();
delete a;
}
The compiler posts an error. If I want to use printNew through A, how can I do it? I thought it must include this feature because this proves useful in various situations.
Having a subclass instance B in a superclass A pointer is called Polymorphism in OOP.
From this A-type pointer, you would not be able to see the member function which exists only in B-type, clearly.
You could use this object as a B-type object by downcasting it though:
B *B = dynamic_cast<B*>(a);
As a has a dynamic type of B*, the cast is safe so a B pointer is returned.
Polymorphism doesn't work like that.
Although a has a dynamic type B*, its static type is A* and as such the pointer to member operator -> cannot reach the printNew function.
Crudely, you could write
virtual void printNew() { cout << "printNew() not implemented";}
in class A.
From C++20 it might indeed be possible to do as you want using reflection, with albeit different calling syntax.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have 2 objects in my C++ program, both extending from the same parent class:
class A, and class B, both extending class base.
Is it possible create an object using class A, and then change it later in the program to class B?
Short answer, no. You cannot safely cast from A to B or B to A. You can safely cast to the base class since A IS_A base class and B IS_A base class but A and not a B and vice versa. There is no portable or safe way to do this. Whilst your compiler might let you do it and whilst it might appear to work the result of casting between to unrelated classes in this manner is undefined.
Incidentally, there is no reason why you can't add a cast constructor to allow A to be constructed from B and vice versa. That would be perfectly safe. You would just use the members of A to initialise the members of B and vice versa. Any members that are not common you'd have to deal with, probably be assigning them default values.
The following code works:
#include <iostream>
class Base {};
struct A : public Base {int a;};
struct B : public Base {int b;};
int main()
{
A *a = new A();
a->a = 1;
B *b = reinterpret_cast<B *>(a);
std::cout << b->b << std::endl;
return 0;
}
This is extremely ugly though and won't work properly if A and B don't have the exact same memory layout. This works if you need a and b to be the same object. If you don't mind them being different objects and residing in different places in memory then you can just write a constructor in B that receives an object of type A or a conversion operator.
This sounds like a classic example of the XY Problem and there probably exists a much more elegant solution to your actual problem.
As others have mentioned, no you cannot do this...technically. You can in fact achieve this effect through convert constructors and virtual functions.
If you write a convert constructor from A to B and B to A:
A::A(B convertFrom); // Convert from B to A
B::B(A convertFrom); // Convert from A to B
And you make the essential parts of each class virtual:
class base
{
virutal void baseClassFunction();
};
class A
{
virtual void baseClassFunction()
{
// Do things for A
}
};
Class B
{
virtual void baseClassFunction()
{
// Do things for B
}
}
Then you can simply make a pointer of type base which can hold a reference to either A or B.
Example bringing it all together;
int main()
{
base *ptr = new A();
bool needs_to_be_B;
...
// Program logic
ptr->baseClassFunction();
...
if(needs_to_be_B)
{
base *tmp = new B(*ptr);
delete ptr;
ptr = tmp;
delete tmp;
}
// ptr is now a B
ptr->baseClassFunction();
}
If you are confused look up virtual functions and convert constructors.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In a method of an object of type class A, I handle an object of class B that has a public method .join(*A).
I want my object of type A calling this someObjectOfTypeB.join(*A) method, to use a pointer to itself as the parameter.
void A::someMethod()
{
B b();
b.join(I want to a to use a pointer to itself as a parameter);
}
A a();
a.someMethod();
Upon further investigation, this was not the problem as I led myself to believe; and is indeed the correct way of doing what I wanted to do.
Try using this:
void A::someMethod()
{
B b;
b.join(this);
}
As #AndrewLazarus and #JonathanWakely commented, use B b; instead of B b(). The later declares a function b without parameters which returns B, and that is not what you want.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Generally in C++, we see same name functions with same arguments in different classes along with virtual keyword. Is it an example of polymorphism? If it is, how and is there any other way to understand polymorphism in c++??
Suppose that you have the following scheme:
class Base {
public:
virtual int foo() = 0;
};
class Derived1 : public Base {
public:
virtual int foo() { return 1; }
};
class Derived2 : public Base {
public:
virtual int foo() { return 2; }
};
Lets say now, that you want to store objects of Derived1 and Derived2 in a container, lets say a std::vector and every time you iterate through the vector to call for each one of its objects function foo. Normally, you'd need two vectors, one for objects of class Derived1 and another one for objects of class Derived2.
Look now how polymorphism comes to our rescue. We can store the addresses of objects Derived1 and Derived2 as pointers to Base objects, and then store these pointers in a std::vector<Base*> v. Now every time we iterate the vector of pointers and call member function foo (e.g., for(auto base : v) base->foo()) the right function foo is called for each one of the objects. This is one of the many aspects of polymorphism which is called upcasting
I hope that the above example of runtime polymorphism gave you a clue, as for how virtual functions and function overriding are related to inheritance and polymorphism.
Update:
Templates are a form of compile time polymorphism take a look at this SO question what is the difference between templates and polymorphism.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have header file as something like following.
class A;
class B;
class C;
Class a {
A *a;
B *b;
C *c;
};
Now, Class a does not using all A, B, C and around 40 others. I have around 40 forward declarations... Is possible to optimize it someone.. So, I can declared pointer to class on need bases instead of wasting memory for all pointer to all 40 odd class?
You can use union with type code or boost::variant
I would recommend for now that you should make a parent class and put as children all of the A,B,C,etc... Then in class use a list of the parent class, and put whatever subclass you need on it. But having this problem is actually due to wrong object oriented design. Learn the principles of OO design of a system in Java for example and then put them in use in C++.
Admitting you cannot rework your classes, and admitting you are using only one at time, you can use a union plus an ID or a "dynamically typed void*":
unsigned gen_id()
{ static unsigned id=0; ++id; return id; }
template<class T>
unsigned id_of()
{ static id = gen_id(); return id; }
class a
{
void* m;
unsigned type;
public:
template<class T>
a(T* p) :m(p), type(id_of<T>())
{}
template<class T>
T* get() const
{ return (id_of<T>()==type)? static_cast<T*>(m): nullptr; }
};
You can access a data as
A* pa = my_a.get();
if(pa) { /* what has to be done with A */ }
If you need more than one, consider a class b holding a vector of a.
For a more "standardized" implementation you can look at boost::any
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
In C++, i am not able to understand, when a base class pointer stores the address of derived class object it is not able to call the derived class member function?
#include <iostream>
using namespace std;
class Base
{
public:
virtual void show()
{
cout<<" In Base ";
}
};
class Derived: public Base
{
public:
int x;
void show()
{
cout<<"In Derived ";
}
Derived()
{
x = 10;
}
};
int main(void)
{
Base *bp, b;
Derived d;
bp = &d;
bp->show();
cout << bp->x;
return 0;
}
According to me:
derived d => allocates the memory to this object(therefore to x also ) say at address 200,
bp = &d; => it allocated the address 200 to bp. Now it should be able to call bp->x?
But it gives a error.
bp->x gives an error because bp is a pointer to an object of type Base, and Base doesn't have a variable called x, only Derived does.
If x was moved up into Base it would be accessible from both Base and Derived if it's public or protected.
Binding of names happens in run time. so at compilation bp is of type base. so compiler doesn't know anything about derived type assignment. so its saying there is no variable called x in base.
That's where concept of virtual functions come into picture. but hey are only for functions not variables.
In C++, i am not able to understand, when a base class pointer stores
the address of derived class object it is not able to call the derived
class member variable?
Well yes you can, you just need to cast the pointer to the class where the member variable is present
cout << dynamic_cast<Derived*>(bp)->x;
Why is bp->x is a error?
Because at compile time, the compiler can't tell what it points to. What if it was actually, a pointer to the base class? Then, x would be completely absent from the underlying object...
To answer the title question: when you have a pointer to base class that actually points to a derived class instance, then a call to a public functions declared virtual in the based class and reimplemented in the derived class will end up being a call to the derived class' implementation of that function (there are subtelties involved, with private/public access and name hiding that may interfere, but this is roughly how it works).