禁止/重定向c++删除
Disallow/Redirect C++ delete?
我有一个模块(dll/so),它导出一个单一的工厂函数,返回一个对象,然后调用。使用接口(纯虚拟),模块的用户可以创建不同的对象。所有的对象创建都是通过接口进行的,因此使用与我的模块相关联的运行时而不是应用程序运行时进行。
由于分配发生在模块内部,因此也需要删除,因为如果应用程序与我的模块具有不同的运行时,则gpf/段故障时间。所以我有一个"release"成员,它执行自删除。
void foo::release(void)
{
delete this;
}
一切正常,但它确实要求模块的用户行为。
我的问题是:- 是否有可能阻止某人直接对我的对象发出删除(或将其重定向到从我的模块内存池中删除)?
- 如果不是作为备份计划,是否有可能在我的对象中检测到这一点,所以我可以抛出一个断言来强制良好的行为?
E。G:
iFoo* foo = createFoo ();
foo->release(); // Allowed and expected
delete foo; // Disallowed
在OP的评论中,@dave建议将纯接口中的析构函数声明为protected
而不是public
。这将完全阻止外部代码(即外部实现类)调用delete
。
class IFoo
{
protected:
virtual ~IFoo() { }
public:
virtual void release() = 0;
};
class Foo : public IFoo
{
public:
void release() override
{
delete this;
}
};
IFoo* createFoo()
{
return new Foo();
}
int main()
{
auto foo = createFoo();
foo->release(); // Expected
delete foo; // Cannot access protected destructor of IFoo
Return 0;
}
由于工厂函数只公开纯接口,如果实现类碰巧提供了公共析构函数,这种方法不会失效。如果Foo
声明了一个公共析构函数,main
仍然会出现编译错误,因为main
不知道它实际上是在处理Foo
。
On Edit:这种方法只会让用户更难以删除资源——它并不能完全阻止它。(我不会删除这个答案,因为它可能仍然有用。)
如果你真的想阻止别人在你的对象上调用delete,那就禁止他们这样做——从你的工厂函数返回一个值类型。
值类型可以是实际对象的一个薄包装,可以提供指针语义,就像智能指针。
一个粗略的例子:
class IFoo
{
public:
virtual ~IFoo() { }
virtual void release() = 0;
};
class Foo : public IFoo
{
public:
Foo() { }
void release() override
{
delete this;
}
};
// Value type with pointer semantics
template <class T>
class Undeletable
{
private:
T* m_resource;
public:
Undeletable(T* resource)
: m_resource(resource)
{
}
T* operator->()
{
return m_resource;
}
};
// Old factory function
IFoo* createFoo()
{
return new Foo();
}
// New factory function
Undeletable<IFoo> createSafeFoo()
{
return Undeletable<IFoo>(createFoo());
}
int main()
{
auto foo = createFoo();
foo->release(); // Expected
delete foo; // Possible but DO NOT WANT
auto safeFoo = createSafeFoo();
safeFoo->release(); // Expected
delete safeFoo; // Compiler says NOPE
return 0;
}
不幸的是,这只会混淆用户仍然可以删除资源的事实。例如:
delete safeFoo.operator->(); // Deletes the resource
相关文章:
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- C++中的线程安全删除
- 如何从存储在std::映射中的std::集中删除元素
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数