-1

In my class C, there is a pointer (var_a) to a class A, so in the destructor of C, I write "delete var_a". In vscode, the code works but doesn't stop automatically after the end of the main. Also, the line where var_a is deleted, is highlighted in yellow. The debug console print :

Warning: Debuggee TargetArchitecture not detected, assuming x86_64.
=cmd-param-changed,param="pagination",value="off"

The hpp :

#ifndef DEF_TEST4
#define DEF_TEST4

#include <iostream>
#include <string>


class A
{   public:
    A();
    A(A const& copy_a);
    virtual std::string printer();
    protected:
    std::string var;
};

class B : public A
{
    public:
    B();
    B(B const& copy_b);
    virtual std::string printer();
    protected:
    std::string var;
};

class C
{
    public:
    C(A* a);
    ~C();
    virtual A* get_a();
    protected:
    A* var_a;
};

#endif

The cpp:

#include "test4.hpp"


A::A() : var("a")
{}

B::B() : var("b")
{}


A::A(A const& copy_a) : var(copy_a.var)
{}

B::B(B const& copy_b) : var(copy_b.var)
{}


std::string A::printer()
{
    return var;
}

std::string B::printer()
{
    return var;
}

C::C(A* a) : var_a(a)
{}

C::~C()
{
    delete var_a;
}

A* C::get_a()
{
    return var_a;
}

The main cpp :

#include "test4.hpp"
#include "test4.cpp"
#include <typeinfo>

int main()
{
    A ca;
    B cb;
    B cb2(cb);
    C cc(&ca);
    C cc2(&cb);

    std::cout << ca.printer() << std::endl;
    std::cout << cb.printer() << std::endl;
    std::cout << cb2.printer() << std::endl;
    std::cout << cb2.A::printer() << std::endl;
    std::cout << cc.get_a()->printer() << std::endl;
    std::cout << cc2.get_a()->printer() << std::endl;
    std::cout << "type cc2.get_a() : " << &typeid(cc2.get_a()) << std::endl;
    std::cout << "type ca : " << &typeid(ca) << std::endl;
    std::cout << "type cb : " << &typeid(cb) << std::endl;

    cc.~C();

}

I suppose that there is a problem, but what? Sorry for the possible bad english, it's not my mother tongue. Thanks for your help.

rioV8
  • 24,506
  • 3
  • 32
  • 49
Keima
  • 19
  • 5
    `cc.~C();` an explicit (completely unnecessary) destructor call will certainly be a problem. Why are you doing that? – πάντα ῥεῖ Nov 22 '21 at 22:04
  • 3
    Also, in order to `delete` an object, it must have been created with `new`. –  Nov 22 '21 at 22:04
  • You are creating `A` and `B` on the stack, their lifetimes exist in the scope of main. It is not your job to delete them. As Frank says, you have to create objects, they go on the heap, to delete them. Smart pointers are preferred so you don't have to mange the lifetimes. – lakeweb Nov 22 '21 at 22:09
  • 2
    `#include "test4.cpp"` Don't include cpp files. Compile and link them instead. This might not be causing you problems now, but as soon as you get out of toy programs, all hell will break lose. – user4581301 Nov 22 '21 at 22:12
  • 1
    When you do get to a case where you need to `delete` a derived class through a base class reference, [make damn sure that base class destructor is `virtual`](https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors). – user4581301 Nov 22 '21 at 22:15
  • This question seems to imply that you [have compiler warnings disabled](https://godbolt.org/z/W71E388ez) or you are choosing not to mention the warnings your compiler is giving you. – Drew Dormann Nov 22 '21 at 22:18
  • You need to look up rule of 0/3/5 - and then smart pointers - and then "Undefined behaviour". You're invoking the last one by calling the destructor explicitly... the behaviour of which, is, as the name implies, undefined. – UKMonkey Nov 22 '21 at 22:22
  • Additional reading: [What is ownership of resources or pointers?](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers) – user4581301 Nov 22 '21 at 22:29
  • Regarding the `cc.~C();`, I did it to experiment, but I followed the general advice and deleted it. – Keima Nov 23 '21 at 19:06
  • I also added a `new` in the constructor of C. Concerning the `#include "test4.cpp"` @user4581301, I don't understand what am I supposed to do after delete it, I don't know how I have to compile and link the cpp. Do you have a tutorial about that, please? – Keima Nov 23 '21 at 19:44
  • Check the compiler documentation. If you have a g++-related compiler, it could be as simple as `g++ main.cpp test4.cpp` I'd use `g++ -O2 -pedantic -Wall -Wextra main.cpp test4.cpp` to get the compiler really working for me, though. – user4581301 Nov 23 '21 at 20:28

1 Answers1

2

As the comments have suggested, there are two problems in the code.

First, cc.~C(): don’t ever call destructors explicitly. There are situations where that’s appropriate, but those are far in your future. The compiler will call the destructor when cc goes out of scope. You don’t need to do it yourself.

Second, in cc and cc2, var_a points at an object that was not created with new; don’t delete it. Just remove that delete var_a; from C::~C(). The objects that var_a points at will also be destroyed when they go out of scope. You don’t need to do it yourself.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165