【问题标题】:C++ : Destructor and pointersC++:析构函数和指针
【发布时间】:2022-01-01 11:22:42
【问题描述】:

在我的C类中,有一个指向A类的指针(var_a),所以在C的析构函数中,我写了“delete var_a”。在 vscode 中,代码可以工作,但不会在 main 结束后自动停止。此外,删除 var_a 的行以黄色突出显示。调试控制台打印:

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

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

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;
}

主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();

}

我想有一个问题,但是什么? 对不起,英语可能不好,这不是我的母语。 感谢您的帮助。

【问题讨论】:

  • cc.~C(); 显式(完全没有必要)的析构函数调用肯定是个问题。你为什么要这么做?
  • 另外,为了delete一个对象,它必须是用new创建的。
  • 您正在堆栈上创建AB,它们的生命周期存在于main 的范围内。删除它们不是您的工作。正如弗兰克所说,您必须创建对象,将它们放在堆上,然后删除它们。智能指针是首选,因此您不必管理生命周期。
  • #include "test4.cpp" 不要包含 cpp 文件。编译并链接它们。现在这可能不会给您带来问题,但是一旦您退出玩具程序,一切都会失败。
  • 当你遇到需要通过基类引用delete 派生类的情况时,make damn sure that base class destructor is virtual

标签: c++ class pointers destructor


【解决方案1】:

正如 cmets 所建议的,代码中存在两个问题。

首先,cc.~C():永远不要显式调用析构函数。在某些情况下这是合适的,但这些都在你的未来。当cc 超出范围时,编译器将调用析构函数。你不需要自己做。

其次,在cccc2中,var_a指向一个不是用new创建的对象;不要delete它。只需从C::~C() 中删除delete var_a;var_a 指向的对象在超出范围时也会被销毁。你不需要自己做。

【讨论】:

  • 感谢您的帮助。
猜你喜欢
  • 2022-01-20
  • 2021-11-28
  • 1970-01-01
  • 2012-04-17
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-25
相关资源
最近更新 更多