Deleting object in destructor with inheritance

Feb 22, 2017 at 6:18pm
I have made two class objects in the constructor like so:

1
2
3
4
5
  executive::executive()
  {
     Vehicle* myCar = new Car(speed);
     Vehicle* myTruck = new Truck(speed);
  }


The deconstructor looks like this:
1
2
3
4
5
6
7
  executive::~executive()
  {
     Vehicle* myCar = nullptr;
     Vehilce* myTruck = nullptr;
     delete myCar;
     delete myTruck;
  }


When I did 'delete myCar' and 'delete myTruck' on their own, it said it wasn't declared in that method.

Valgrind still tells me there are memory leaks in the executive::executive() method where I make the class objects.
What's a better way to resolve this issue?

Thanks.
Feb 22, 2017 at 6:35pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

struct Vehicle{double m_speed; Vehicle(const double& speed): m_speed(speed){} virtual ~Vehicle(){}};
struct Car : public Vehicle{using Vehicle :: Vehicle;  ~Car(){std::cout << "Goodbye car with speed " << m_speed << "\n";}};
struct Truck : public Vehicle{using Vehicle :: Vehicle; ~ Truck(){std::cout << "Goodbye truck with speed " << m_speed << "\n"; }};
struct Executive
{
   Vehicle* myCar;
   Vehicle* myTruck;
   Executive(const double& carSpeed, const double& truckSpeed)
   {
       myCar = new Car(carSpeed);
       myTruck = new Truck(truckSpeed);
   }
    ~Executive()
   {
       delete myCar;
       myCar = nullptr;
       delete myTruck;
       myTruck = nullptr;
   }
};
int main()
{
    Executive (70, 60);
}

edit: dtor added in class
Last edited on Feb 22, 2017 at 7:20pm
Feb 22, 2017 at 6:51pm
It still says that 'myCar' and 'myTruck' are not declared in that scope.
Feb 22, 2017 at 7:00pm
see lines 8 and 9 of my program, you need to do something similar
Feb 22, 2017 at 7:23pm
contrast raw ptr vs std::unique_ptr vis-a-vis commented out code below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <memory>

struct Vehicle{double m_speed; Vehicle(const double& speed): m_speed(speed){} /*virtual ~Vehicle(){}*/};
struct Car : public Vehicle{using Vehicle :: Vehicle; ~Car(){std::cout << "Goodbye car with speed " << m_speed << "\n";}};
struct Truck : public Vehicle{using Vehicle :: Vehicle; ~Truck(){std::cout << "Goodbye truck with speed " << m_speed << "\n";}};
struct Executive
{
   std::unique_ptr<Vehicle> myCar = nullptr;
   std::unique_ptr<Vehicle> myTruck = nullptr;
   Executive(const double& carSpeed, const double& truckSpeed)
   {
       myCar = std::make_unique<Vehicle>(Car(carSpeed));
       myTruck = std::make_unique<Vehicle>(Truck(truckSpeed));
   }
   /*~Executive()
   {
        delete myCar;
        myCar = nullptr;
        delete myTruck;
        myTruck = nullptr;
   }*/
};
int main()
{
    Executive (70, 60);
}

Feb 23, 2017 at 3:12am
In the case of raw pointers the copy assignment operator and copy constructor should be deleted as an object of type Executive has two data members, myCar, myTruck, that manage, in turn, a Car and a Truck object respectively created on the heap. With copy construction or assignment if myCar and myTruck are assigned to the corresponding data-members of the newly created object then we have two pointers to the same Car and Truck object and if delete is called on either of the pointers then the other pointer is left dangling.
An alternative would be to create a new Car and a new Truck object with same m_speed values as the right-hand side object and assign the pointer data-members of the new Executive object to these but that would just be replicating the ctor.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <algorithm>

struct Vehicle{double m_speed; Vehicle(){} Vehicle(const double& speed): m_speed(speed){} virtual ~Vehicle(){}};
struct Car : public Vehicle{using Vehicle :: Vehicle;  ~Car(){std::cout << "Goodbye car with speed " << m_speed << "\n";}};
struct Truck : public Vehicle{using Vehicle :: Vehicle; ~ Truck(){std::cout << "Goodbye truck with speed " << m_speed << "\n"; }};
struct Executive
{
   Vehicle* myCar = nullptr;
   Vehicle* myTruck = nullptr;
   Executive(const double& carSpeed, const double& truckSpeed)
   {
       myCar = new Car(carSpeed);
       myTruck = new Truck(truckSpeed);
   }
    ~Executive()
   {
       delete myCar;
       myCar = nullptr;
       delete myTruck;
       myTruck = nullptr;
   }
   Executive (const Executive& rhs) = delete;
   Executive& operator = (const Executive& rhs) = delete;
   Executive (Executive&& rhs)//move ctor
   {
       myCar = rhs.myCar; rhs.myCar = nullptr;
       myTruck = rhs.myTruck; rhs.myTruck = nullptr;
   }
   bool operator == (const Executive& rhs)
   {
       return ((myCar == rhs.myCar) && (myTruck == rhs.myTruck));
   }
   Executive& operator = (Executive&& rhs)//move assignment
   {
       if(*this == rhs)return *this;
       std::swap(myCar, rhs.myCar);
       std::swap(myTruck, rhs.myTruck);
       return *this;
   }
};
int main()
{
    Executive a(70, 60);
    //Executive b(a);//error: use of deleted function
    Executive c (std::move(a));//OK, uses move constructor
    //Executive d = c; //error, use of deleted function
    Executive e = std::move(c);//OK: move assignment
}


In the case of std::unique_ptr, the copy ctor and copy assignment operators for Executive would be deleted automatically as it has std::unique_ptr data-members. The Executive move ctor will, in turn, use move assignment as the data-members are unique_ptr's while the move assignment operator remains unchanged:
1
2
3
4
5
Executive (Executive&& rhs)//move ctor
   {
       myCar = std::move(rhs.myCar); /*rhs.myCar = nullptr;*/
       myTruck = std::move(rhs.myTruck); /*rhs.myTruck = nullptr;*/
   }

Last edited on Feb 23, 2017 at 3:14am
Topic archived. No new replies allowed.