是否可以像普通指针一样构造一个行为和行为(就语法而言)的指针类型,除了你不能在它上面调用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,因为它属于别人。
答案 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