c ++ Delete derived from base class like QObject 做

c++ Delete derived from base class like QObject do

我有一个问题。 我怎样才能像 QObject 那样用析构函数做一些事情?

Class Person : public QObject{
   //...
   public:
   Person(QObject *p = nullptr) : QObject(p){}
   virtual ~Person() { QDebug() << "name: " << name << "\n";}
   // Getters, Setters
};

int main(int argc, char* argv[]){
    QCoreApplication a(argc, argv);
    Person *Cris{new Person};
    Person *Henry{new Person(Cris)};
    Cris->setName("Cris");
    Henry->setName("Henry");
    delete Cris;
}

输出是:

name: Cris.
name: Henry.

我只想删除 Base class,而 Derived classes 将自行删除。像 QT 一样,但没有 QT。


已编辑: 这是我的代码示例:

#include <iomanip>
#include <iostream>
#include <list>
#include <memory>
#include <string>
#include <vector>

using namespace std;

class Base;
class Derived;

class Storage {
  public:
    static void addBase(Base **b) { l_base.push_back(*b); }

    static void printBase() {
        std::cout << "\n // ------------------------------------ // \n";
        for (auto *fl : l_base) {
            cout << fl << endl;
        }
    }

    static void deleteBase() {
        std::cout << "\n // ------------------------------------ // \n";
        // for (auto *fl : l_base) {
        //  // Derived *dd = reinterpret_cast<Derived *>(fl);
        //  cout << l_base.front() << endl;
        //  cout << l_base.back() << endl;
        //  delete l_base.back();
        //  l_base.pop_back();
        // }
        auto d = l_base.front();

        while (!l_base.empty()) {
            if (d != l_base.front()) {
                delete l_base.back();
                l_base.pop_back();
            } else {
                l_base.pop_front();
            }
        }

        // l_base.clear();
        cout << "\nCleared.\n";
    }

  private:
    // Base *bp;
    static list<Base *> l_base;
};

class Base {
    friend class Storage;

  protected:
  public:
    Base(Base **b = nullptr, string n = "") {
        if (n == "") {
            name = "Empty";
        } else {
            name = n;
        }

        if (b != nullptr) {
            // bp = b;
            bp = this;
            Storage::addBase(&bp);
            Storage::printBase();
        }

        std::cout << "\n Base Constructor.\n "
                  << "And names: " << name << "\n";
    }                 //    Constructor
    virtual ~Base() { //
        Storage::deleteBase();
    } //    Destructor

    bool operator==(Base *b) {
        if (this == b) {
            return true;
        }
        return false;
    }

    bool operator!=(Base *b) { return !(this == b); }

  private:
    Base *bp;
    // Derived *dp;
    string name;
    // static _init s_init;

}; //   Base

class Derived : public Base {
  private:
    string name;

  protected:
  public:
    Derived(Base *b = nullptr, const string n = "") //
        : Base(&b, n), name(n) {
        std::cout << "\n Derived Constructor.\n ";
        //   << "Show Address: " << b << "\n";
    } //    Constructor
    virtual ~Derived() {
        std::cout << "\n // ------------------------------------ // \n";
        std::cout << "\n // ------------------------------------ // \n";
        std::cout << "\n // ------------------------------------ // \n";
        std::cout << "\n // ------------------------------------ // \n";
        std::cout << "\n // ------------------------------------ // \n";
        std::cout << "\n // ------------------------------------ // \n";
        std::cout << "\n Derived ------- Destructor.\n "
                  << "name: " << name;
    } //    Destructor

    void derived_dSome() { std::cout << "\n Derived_dSome.\n "; }

}; //   Derived

// Static
list<Base *> Storage::l_base;
// Base::_init Base::s_init;

/* Main */
int main(int argc, char const *argv[]) {

    Derived *a{new Derived};
    Derived *b{new Derived(a, "Second")};
    Derived *c{new Derived(a, "Third")};

    cout << "\n\n ================== List of Derived: ==============="
         << "\na: " << a << "\nb: " << b << "\nc: " << c;

    delete a;
    // delete d;

    std::cout << "\n\n---------------------"
              << "\n End of the program.\n"
              << "---------------------\n";
    return 0; // Ending program
} //    Main

有点乱。我已经尝试过很多次了。

谢谢。

这不是推导。当您调用此构造函数时:

Person *Henry{new Person(Cris)};

它将 Henry 创建为 Cris 的 child。在Qt中,每个QObject可以有很多children。 Child object 会在 parent 被删除时被删除。这是通过保留 children 的列表并在调用 parent 析构函数时删除它们来完成的(它比 Qt 中的 signal/slots 复杂得多,其他事情应该处理为出色地)。 您可以通过为 objects 使用标准容器保留 children 的列表来创建类似的实现。

我要在前面加上前缀,说我实际上并没有测试它,但代码应该是可行的。

我不认为你真的需要额外的 Storage class,这可以直接在 Base class 中完成。此外,在 Derived class 的构造函数中,您正在传递一个指向父级指针的指针。你只想传递指针本身,否则你会得到一些错误,因为你将引用不存在的对象。

此外,我相信您在 Base class 的构造函数中调用 Storage::deleteBase() 函数会删除太多内容,并使对象过早失效。这将导致未定义的行为。

class Base {
public:
    Base( Base *parent = nullptr ) {
        if ( parent ) 
            parent->addChild( this );
    }
    virtual ~Base() {
        for ( Base *child : children ) 
            delete child;
    }
private:
    void addChild( Base *child ) {
        children.push_back( child );
    }
    std::vector<Base*> children;
};

class Derived : public Base {
public:
    Derived( Base *parent = nullptr ) : Base( parent ) {}
}