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 ) {}
}
我有一个问题。 我怎样才能像 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 ) {}
}