在半个多月以前 看完了深度探索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是两步操作
- 调用对象的析构函数 (析构函数中调用 会导致递归)
- 释放相关空间
成员变量指针类型
#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_();
}
}
}