没有删除操作符的指针类型

时间:2013-01-27 18:01:06

标签: c++ smart-pointers

是否可以像普通指针一样构造一个行为和行为(就语法而言)的指针类型,除了你不能在它上面调用delete(可能还有预处理器宏)?

使用示例:

borrowed_ptr<int> ptr = new int[42]; 

ptr[12] = 1;
cout<<ptr[12]<<endl; //prints 1

delete ptr; //error: no operator delete for borrowed_ptr<int>

borrowed_ptr<int> ptr2 = new int(2);
delete ptr2; //error

这也应该有用

template<typename t>
void func(borrowed_ptr<t> *arg)
{
   delete arg; //error
}

//somewhere else
int *t = new *int;
func(t);

然而,“反向分配”不应该起作用。

borrowed_ptr<int> foo = new int(2);
int* bar = foo; //error

声明borrowed_ptr时是否需要*对我来说无关紧要。像

这样的代码非常重要
template <typename T>
void foo(T* whatever)
{
    //do something with whatever
   delete whatever; 
}

template <typename T>
void bar(T* whatever)
{
    //do something with whatever
}

可以使用这个借用_ptr这样调用:

borrowed_ptr<int> a = new int(2);
foo(a); //error, function tries to delete
bar(a); //fine, and has the same semantics as handing over a raw int*

注意:当指针类型自行删除时,我不希望删除数据。它应该只是一个无法删除的借来的ptr,因为它属于别人。

7 个答案:

答案 0 :(得分:0)

在谷歌上看到C ++中各种智能指针的实现。有很多很好的例子。

答案 1 :(得分:0)

我猜你真正想要的是std::shared_ptr

答案 2 :(得分:0)

您可以使用unique_ptr来实现此目的:

unique_ptr<int[]> ptr(new int[10]);

无需调用delete[],无法调用delete(没有隐式转换为封装的指针类型),并提供了下标运算符的重载:

cout << ptr[1];

答案 3 :(得分:0)

delete运算符需要内置指针类型,因此任何智能指针都可以实现。大多数常见的功能都有一些额外的功能,您可能想要也可能不想要;如果有必要的话,写自己的并不难;只需将指针包装在一个类中,该类为操作符*->提供重载。模板化的伪拷贝构造函数和赋值运算符也可以提供隐式类型转换。

答案 4 :(得分:0)

是的,您可以使用std::unique_ptr。不要忘记为此包含<memory>

#include <memory>

int main() {
   std::unique_ptr<int[]> a(new int[2] {1, 2, ...});

   a[1]; // 2
}

答案 5 :(得分:0)

大多数问题都源于对热量学的不当使用:您不删除指针,删除他们指向的内容。

此时,您需要一个模仿指针的对象,因此,据我所知,您的第一行应该是

borrowed_ptr<int> ptr = new int[42]; 

而不是borrowed_ptr<int> *ptr = new int[42];。这使得ptr成为“on stack object”,不能调用任何删除。

borrowed_ptr

template<class T>
class borrowed_ptr
{
public:
    borrowed_ptr() :p() {}
    explicit borrowed_ptr(T* p_) :p(p_) {}

    T* operator->() const { return p; } //don't include this operator if just want an array-like behavior
    T& operator*() const { return *p; } p; } //don't include this operator if just want an array-like behavior
    T& operator[](int x) const { return p[x]; }

private:
    T* p; //< here is where pointer lives
};
只需要

答案 6 :(得分:0)

您想要的是一个无所有权的“智能”指针,该指针没有引用计数,并且可以进行指针算术运算。

从C ++ 17开始,标准库中没有这种类型。最接近的等效项 1 是建议的 2 std::experimental::observer_ptr,但是由于您希望禁止“删除”的原因,它在设计上不允许指针算术:容易出错。标准库中唯一其他非拥有的智能指针是std::weak_ptr,尽管它执行引用计数并要求所有者使用std::shared_ptr来管理其生命周期,并且也不允许指针算术

您必须自己实现它,幸运的是,这非常简单。您可以从observer_ptr的{​​{3}}开始,并为operator[]和其他算术运算符添加重载。

但是,请注意,通常认为将裸指针(或引用)作为非拥有资源的指针的原始指针(或引用)通常是更好的做法,或者是更多的“惯用C ++”。有关资源管理的信息,请参见implementation。这使其简单,避免代码混乱,并提高了互操作性(如constness,智能指针倾向于“感染”代码的其他部分)。原始指针确实确实容易出错,但是大多数错误可以通过静态代码分析来捕获。话虽如此,我同意非所有者智能指针在适当使用时会有其用例。

1 如此接近以至于实际上,有人主张在C++ Core Guidelines中重命名borrowed_ptr

2 参见提案this thread