由muduo tie引出的 delete this

在半个多月以前 看完了深度探索C++对象模型, 然而只是粗略的过了一遍. 并没有结合具体的例子去深刻的理解下

如果delete this 不会遇到 那这样呢?

#include <cstdio>

void Delete();

class Foo
{
public:

Foo()
{
bar_ = 111111;
}
~Foo()
{
printf("~Foo()\n");
}

void Bar1()
{
printf("Bar1()\n");
}
void Bar()
{
Delete();
printf("bar: %d\n", bar_);
Bar1();
}

int bar_;
};

Foo* foo = nullptr;
bool del = false;
void Delete()
{
if (!del)
{
del = true;
delete foo;
}
}

int main()
{
foo = new Foo;
foo->Bar();
printf("\n");
foo->Bar();

return 0;
}

程序安然的结束了, 但是发现 成员变量bar的值已经被初始化了, 由于delete释放了内存.

~Foo()
bar: 0
Bar1()

bar: 0
Bar1()

同时delete是两步操作

  1. 调用对象的析构函数 (析构函数中调用 会导致递归)
  2. 释放相关空间

官方解释

成员变量指针类型

#include <cstdio>
#include <functional>

class Foo
{
public:

void Bar1()
{
if (bar_)
{
bar_();
}
}

void Bar2()
{
bar_();
}
std::function<void()> bar_;
};

Foo* foo = nullptr;

void PrintfBar()
{
printf("Bar\n");
}

int main()
{
foo = new Foo;
foo->bar_ = PrintfBar;

foo->Bar1(); // Bar
foo->Bar2(); // Bar

delete foo;

foo->Bar1(); // Segmentation fault (core dumped)

foo->Bar2();

return 0;
}

测试后所有对指针型成员变量的 解引用操作都会导致Segmentation fault (core dumped) 所以下面的代码也有了解释

一个困扰我很久的BUG 即为程序会在HandleEvent触发Segmentation fault (core dumped)的原因找到了

void Channel::HandleEvent()
{
/**
* lock增加TcpConnectionPtr的引用计数 防止从TcpServer中erase后 直接销毁TcpConnection
*
* 否则如果不增加引用计数 当TcpConnection被销毁后, 所管理的Channel也将会被销毁
* 在这之后 不能再使用TcpConnection和Channel的任何 成员函数和成员变量
*
* 有点类似于在一个 new出来的对象的成员函数中 delete自己
* 详见 https://stackoverflow.com/questions/7039597/what-will-happen-if-you-do-delete-this-in-a-member-function
*
* 经过查阅后自己对深度探索C++对象模型 有了更深得理解
*/
std::shared_ptr<void> guard = tie_.lock();
if (!guard)
{
LOG_WARN("connection: %s is closed", connection_name.c_str());
}

if (event_ & XEPOLLIN)
{
if (readable_callback_)
{
readable_callback_();
}
}
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。