Virtual function, how does they work? [closed] - c++

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).

Related

C++ Access "parents" class members [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm new into learning C++.
And what I've learned is that using global var is not a good practise.
And I don't wanna use static var, since they behave like "global" var as well, if I'm correct.
In the code below I want class B to get access to its "parents" member, is that possible?(see class B constructor)
Or how should I approach this, where I want to access var/members between classes?
Friends, seems not to be the way either.
class A {
public:
int number_I_want = 987;
A() {
B* classB = new B();
}
};
class B {
public:
int nr = 0;
B() {
nr = this->parent->numer_I_want; /// Here I wanna access the "parent" A's member with value 987
cout << nr * nr;
}
};
int main() {
A* classA = new A();
return 0;
}
Class A is The parent class so if the members/fields are not private . you can access them in class B. But the class B must Be the child of class A. You have to extend class b from A. And if you have parametrized constructor of parent class you must initialize classA constructor from class B
In C++, there is no parent\child relation for object. Sometimes it gets confusing with people coming from languages with object memory model (which are either VM-based or interpreters). Parent there is an object owning this one. C++ uses abstract memory model. If a class Bis inherited from other class A, class A is abase class of B. Base class and class members are subobjects of given class, meaning their storage is part of enclosing object's storage. Consecutively base class's members are subobjects too and are accessible as class members with consideration of access level and inheritance level (private, public, protected).
Enclosing object owns included ones and call to its destructor results in their destruction.
If you need actual parent\child relation , you have to implement it and pass a pointer (?) to parent into child's constructor, while it have to be able to register self within given parent.
Some C++ framework emulate object model by using metaprogramming technique, e.g. Qt Framework's QObject may have a parent and list of children.
Using pointer to >>this<< keyword when creating a "child" class worked for me.
class A {
public:
int nr;
A();
};
class B {
public:
B(A* classA) {
std::cout << "Written in class B, value from class A: "<< classA->nr;
};
};
A::A() {
nr = 77;
B* classB = new B(this);
delete classB;
}
int main() {
A* classA = new A();
delete classA;
return 0;
}

How to access the new member functions of child class? [closed]

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.

c++ why would you pass a reference to a base class to a constructor of a derived class [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In c++ is there a reson why you would pass a reference to a base class to a constructor of a derived class? Why would you want to do this?
Here is a basic example:
#include<iostream>
using namespace std;
class Base
{
int x;
public:
virtual void fun() = 0;
int getX() { return x; }
};
// This class ingerits from Base and implements fun()
class Derived: public Base
{
int y;
public:
Derived(Base& object);
void fun() { cout << "fun() called"; }
};
Typically, arguments are passed to constructors because the state of the arguments can be used to initialize the state of the object that is being constructed. Same applies to this case.
Non-const reference arguments can be (and nearly always are) used to modify the referred object.
In c++ is there a reason why you would pass a reference to a base class to a constructor of a derived class?
There is usually one reason why reference to an object would be passed to a constructor, does not really matter if that object type related to consttructed one or not - to construct this type you need information from that object. Using lvalue reference instead of const one could mean either bad design or ctor would need to modify passed object or keep non-const reference/pointer to it.
I would think the question is "why pass the base class reference instead of the derived class reference?". If so, the reason Base& is passed instead of Derived& is that the former allows you to pass an OtherDerived& reference, given that OtherDerived inherits Base. This is called polymorphism and is quite a thing in C++.
Here's pretty much the same question, but with a function instead of a constructor.

C++ dynamic_cast returning NULL although object is of a derived type [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a strange problem, where a dynamic_cast is returning a NULL pointer although the object given in the expression is of a derived type with an inheritance path to the type of the cast.
Unfortunately, i cannot post original code, so here is the situation roughly reconstructed:
I have a clas hierarchy of the following type:
class A
class B
class C : public A, B
class D : public C
All classes have virtual members.
Now assume I have an object of concrete type D.
In a function where this object is passed in as a B*, i have a cast of this type:
C* func(B* pObject)
{
return dynamic_cast<C*>(pObject);
}
The cast returns NULL although the object seems well defined.
VC++ reports it as being a D when looking at the object in debugger when hovering over pObject. (might this be misleading?)
Is this cast supposed to work?
Imo this cast should be allowed. Am i missing something?
What can i do to analyse this issue?
Could there be an issue with the multiple inheritance?
This is on Visual C++ 2013 Pro if it makes any difference.
Your problem is elsewhere.
Consider
#include <iostream>
struct A {};
struct B {virtual ~B() = default;};
struct C : A, B {};
struct D : C {};
int main()
{
D d;
D* pd = &d;
B* pb = dynamic_cast<B*>(pd);
C* pc = dynamic_cast<C*>(pb);
std::cout << pc; // this is not nullptr
}
This proves that C* is reachable from B* for an pointer to an object of type D, when only B (the source type in the second cast) is explicitly polymorphic.
See https://ideone.com/ifxYgV

Can I change the type of an object at runtime in C++ [closed]

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.