-4

Is it possible to delete derived class object in proper way when derived class pointer was assigned to base class pointer? Lets consider following situation:

#include <stdio.h>
#include <iostream>
#include <map>
#include <stddef.h>


class Signal{
    public:
    Signal (int val) : x(val){};
    int x;
    
    virtual ~Signal(){
        std::cout<<"base class destructor"<<std::endl;
    }

};


class Timer : public Signal{
    public:
    Timer (int val) : Signal(val), y(val+1){};
    double y;  
    virtual ~Timer(){
        std::cout<<"derived class destructor"<<std::endl;
    };
};


int main()
{
    std::cout<<"start"<<std::endl;
    Timer* t = new Timer(9);
    Signal* s = t;
    
    delete s;
    std::cout<<t->x <<std::endl;
    std::cout<<t->y <<std::endl;
    s = NULL;


if (t != NULL){
    delete t;
}
    std::cout<<"end"<<std::endl;
    return 0;
}

This will print:

start derived class destructor base class destructor -340049904 10

...Program finished with exit code 0 Press ENTER to exit console.

I just wonder if it is possible. Of course i try to avoid following asigment "Signal* s = t;" and it works.

I expected, that "end" will be printed but it is not. It seems like the program stops on "delete t". The same behavior I am observing with and without "t != NULL" check.

  • `delete s;` is ok as - _"...or a pointer to a base subobject of a non-array object created by a new-expression. ..."_ [delete](https://en.cppreference.com/w/cpp/language/delete). However the following 2 lines after the delete are UB as the object has been deleted. `delete t;` is also UB as the object has been deleted. – Richard Critten Dec 22 '22 at 14:49
  • 1
    `std::cout<x <y < – πάντα ῥεῖ Dec 22 '22 at 14:50
  • On a side note, passing a null pointer to `delete` is fine, so there is no need to check. – molbdnilo Dec 22 '22 at 14:52
  • You're wondering if *what* is possible? `delete s;` destroys the object, and trying to access it after that point is undefined. Also, `t != NULL` is always true since you never assign `t` a new value. (Are you assuming that you can determine whether an object exists by comparing with the null pointer?) – molbdnilo Dec 22 '22 at 14:53
  • 1
    `s` and `t` point to the same object. Once you `delete s;` you deleted the pointed object, meaning you deleted the object `t` was also pointing to. `t` now has an invalid pointer value and trying to dereference it is an error, it doesn't point to anything in particular. `Signal s = t;` doesn't copy the object, it just makes another pointer that points to the same thing. – François Andrieux Dec 22 '22 at 14:55
  • Some revision of the basic concept of pointers is needed. Copying a pointer copies the pointer, not the object being pointed to. – john Dec 22 '22 at 14:59
  • 2
    Consider: I point at an apple and say "there's an apple!". Then somebody else points at the same apple and says "there's a fruit!" and immediately throws the fruit in the garbage. I haven't moved a finger. Am I still pointing at an apple? Can I eat it? – molbdnilo Dec 22 '22 at 15:00

1 Answers1

1
Timer* t = new Timer(9);
Signal* s = t;

delete s;
std::cout<<t->x <<std::endl;

You cannot access t, with cout << t->x after delete s;. This deletion destroyed both t and s, which are actually the same object.

Just wait to be done with printing (or anything else) before deleting.

Jeffrey
  • 11,063
  • 1
  • 21
  • 42