1

是否可以构造一个指针类型,其行为和行为(就语法而言)像普通指针一样,除了你不能对它调用 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

声明借用_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
}

可以像这样使用这个 borrowed_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,因为它属于别人,所以不能删除。

4

7 回答 7

0

delete运算符需要内置指针类型,因此任何智能指针都可以解决问题。大多数常用功能都有一些附加功能,您可能想要也可能不想要;如有必要,自己编写并不难;只需将指针包装在一个类中,该类为一元运算符*和提供重载->。模板化的伪复制构造函数和赋值运算符也可以提供隐式类型转换。

于 2013-01-27T18:09:08.587 回答
0

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

#include <memory>

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

   a[1]; // 2
}
于 2013-01-27T18:10:17.240 回答
0

大多数问题源于对热学的不当使用:您没有删除指针,而是删除了它们指向的内容。

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

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

而不是borrowed_ptr<int> *ptr = new int[42];。这使得ptr它成为一个“堆栈对象”,不能对其调用删除。

为了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
};

这就是所有需要的。

于 2013-01-27T18:29:43.987 回答
0

在 google 上查看 C++ 中智能指针的各种实现。有很多很好的例子可用。

于 2013-01-27T18:03:49.097 回答
0

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

于 2013-01-27T18:04:24.970 回答
0

你可以使用 aunique_ptr来达到这个目的:

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

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

cout << ptr[1];
于 2013-01-27T18:04:57.773 回答
0

您想要的是一个没有引用计数的非拥有“智能”指针,并且允许指针算术。

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

你必须自己实现它,幸运的是这很简单。您可以从 的实现开始observer_ptr,然后添加 foroperator[]和其他算术运算符的重载。

但是,请注意,对于指向资源的非拥有指针,简单地使用原始指针(或引用)通常被认为是更好的做法,或更“惯用的 C++”。例如,请参阅有关资源管理的C++ 核心指南。这使它保持简单,避免代码混乱,并增加互操作性(如常量,智能指针倾向于“感染”代码的其他部分)。原始指针确实有点容易出错,但大多数错误都可以通过静态代码分析来发现。话虽如此,我同意非拥有智能指针在适当使用时有其用例。

1太接近了,事实上,有人主张borrowed_ptr这个线程中重命名它

2在此处查看建议

于 2018-07-02T08:50:56.613 回答