我正在存储需要对对象进行操作的操作,但我不想使用继承.所以我使用的技术是拥有一个非成员函数,它接受一个指向对象的指针,然后将它存储在对象中,如下所示:
struct command
{
command()
{
}
command(const std::function<void()>& action)
: action(action)
{
}
int n;
std::function<void()> action;
};
void test_action(command* this_ptr)
{
this_ptr->n = 5;
}
int main()
{
command com(std::bind(test_action, &com));
com.action();
std::cout << com.n;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是安全command com(std::bind(test_action, &com));吗?还是未定义的行为?
我不明白这个:
3.8/1"类型T的对象的生命周期在以下情况下结束: - 如果T是具有非平凡析构函数(12.4)的类类型,则析构函数调用开始,或者 - 对象占用的存储器被重用或释放. "
如果生命周期在析构函数启动之前结束,那是不是意味着访问析构函数中的成员是未定义的行为?
我也看到了这句话:
12.7"对于具有非平凡析构函数的对象,在析构函数完成执行后引用该对象的任何非静态成员或基类会导致未定义的行为."
但它并不清楚析构函数中允许的内容.
据我所知,下面的代码是正确的:
#include <iostream>
#include <functional>
struct A
{
std::function<void ()> func;
int value = 5;
~A() { func(); }
};
int main()
{
A* p_a = new A();
p_a->func = [&p_a]() { std::cout << p_a->value; };
delete p_a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但以下代码不是并导致分段错误:
#include <memory>
int main()
{
std::unique_ptr<A> p_a = std::make_unique<A>();
p_a->func = [&p_a]() { std::cout << p_a->value; };
p_a = {};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
std::unique_ptr 首先清除其内部指针,然后删除该对象,从而防止访问被销毁的对象。
它是做什么用的?这背后的逻辑是什么?