C++ - Deleting a polymorphic pointer [closed] - c++

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 5 years ago.
Improve this question
class A { int* a; };
class B : public A { int*b; };
int main() {
A* ptr = new B();
delete ptr;
}
class A is a pure virtual interface class and class B inherits from class A. When we delete ptr which destructor will be called? The one from the A class or the one from from the B class?

Comment: First of, why do you have code outside any function? Statements only make sense when there are within the body of a function, like main.
Assuming the statements you posted were supposed to go into main:
Answer:
delete ptr will call the destructor of A. The compiler will not 'think' any further than this.
Reason: All methods (including the destructor) are non-virtual by default. In your case, you did not specify that the destructor should be virtual. The compiler sees that you are calling the destructor on a A* pointer, so it calls the destructor of A.
What if I had specified that Class A destructor was virtual? Would it still call the destructor of Class A?
Answer: If it were virtual, it would call the destructor of B, because the actual type of the object would be determined during the execution of the program.
See more about virtual functions and polymorphism here.

Related

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.

Do C++ abstract classes need to obey the rule of five? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
When implementing an abstract class like this:
class Base
{
public:
virtual ~Base() = default;
virtual void foo() = 0;
};
Does this interface have to obey the rule of five i.e. do I have to add a copy constructor, copy assignment operator, move constructor and move assignment operator?
I'd figure that an instace of type Base can not be instantiated due to the pure virtual member function and thus providing default implementations for the other special member functions might serve no real purpose.
Is there any use-case/example that would require me to provide the other special member functions?
"abstract" is irrelevant here. A class needs its own copy constructor, copy assignment operator, etc. if it has data that won't be properly copied by the default versions. Full stop. The presence or absence of pure virtual functions does not change this. Your example doesn't have any data, so doesn't have an issue here.
Actually it is the contrary. I would consider deleting copying and assignment of a class that is supposed to be only an interface class to avoid slicing. Consider
class Base {
public:
virtual ~Base() {}
};
class D1 : public Base {
int i;
public:
~D1() override {}
};
class D2 : public Base {
int i;
double d;
public:
~D2() override {}
};
you could write something like this
vector<Base> vec;
D1 d;
D2 e;
vec.push_back(d);
vec.push_back(e);
. You would try to squeeze an object of size D2 into a much smaller object of type base. By deleting copy and assignment you do prevent the user or yourself doing that.

C++ Inheriting base Class Destructor [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 8 years ago.
Improve this question
I'm working on a game, where i have a derived player class that inherites from a Parent GameObject Class, What i want to accomplish is calling the base class destructor inside of the derived class destructor, can i do that?
Example:
// Base Class
class A
{
public:
// other code goes here...
~A();
protected:
int a;
}
// ...
// ...
// Base Class Destructor
A::~A()
{
// sets a back to 0
a = 0;
}
// Derived Class
class B : public A
{
public:
// other code goes here...
~B();
}
// Derived Class Methods
B::~B()
{
// Calls for Base Class Destructor, How can i accomplish this
A::~A();
}
Parent class' destructor is automatically called. Calling order of destructors is opposite to order of constructors; so that, it's ok to rely on parent class' fields in destructor of derived class.
You should better declare destructor as virtual. It's needed to determine correct destructor if you delete object of derived class through base class pointer.
Try adding trace output in destructors to ensure what calling order of destructors is.

Virtual function, how does they work? [closed]

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

TIP: in C++, having a method where "this" is not used is not good design [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 9 years ago.
Improve this question
Under the hood, a C++ method of a class is like a C function whose first parameter is an instance of the class - or struct.
For example:
void Foo::Do();
would be equivalent to this declaration in C:
void Do(Foo* this);
Hence, using a member m_someMember from within a method is like using this->m_someMember from inside the C function.
After so many years of C/C++ programming experience, I just recently asked myself: What if I call a method from an instance pointer that is NULL???
My guess was: If the method refers to no member at all, when why would it crash?
So I did a quick test (on a Windows platform, with Visual C++ 2008):
class Foo
{
public:
Foo() {}
virtual ~Foo() {}
void Do();
};
void Foo::Do()
{
cout << "Calling 'Do' for " << this << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Foo foo;
foo.Do();
Foo* pNullFoo = 0;
pNullFoo->Do();
return 0;
}
Which gives an output like:
Calling 'Do' for 0038FE5C
Calling 'Do' for 00000000
This could be an hassle when doing post-mortem debugging of a crash over an instance pointer that is null. You might think that this method cannot be called if this is invalid.
On the other hand, if the method is declared virtual:
virtual void Foo::Do() { ... }
Then the line:
pNullFoo->Do();
will produce an page fault exception. Why? Because instances of a class with virtual methods have a pointer to the vtable to the child class virtual methods they belong to.
So the first thing the compiler would do is to make pNullFoo to access its vtable member, then bang!
In conclusion, this is better design to have non contextual functions like Do be implemented as procedural routines than methods, unless they are virtual.
Calling a member function on a NULL pointer invokes undefined behavior. Undefined doesn't mean it's going to crash, nor does it mean it's going to do the right thing - it's undefined. Anything could happen.
The only time I've seen this in production code is with Microsoft's CWnd::GetSafeHWND function. But since they wrote the compiler, they can get away with it.
The proper design for member functions that don't need to access any member data is to have them defined as static:
static void Do();
Then call it like:
Foo::Do();
And you don't even need to have an object or a pointer to do that.