实现智能指针 - 使用模板进行动态分配
我正在编写一个智能指针 countedptr ,但遇到了障碍。 countedptr 的基本功能是像任何其他智能指针一样工作,并且还统计有多少指针指向单个对象。到目前为止,代码是:
[已解决]
#include "std_lib_facilities.h"
template <class T>
class counted_ptr{
private:
T* pointer;
int* count;
public:
counted_ptr(T* p = 0, int* c = new int(1)) : pointer(p), count(c) {} // default constructor
explicit counted_ptr(const counted_ptr& p) : pointer(p.pointer), count(p.count) { ++*count; } // copy constructor
~counted_ptr() { --*count; delete pointer; }
counted_ptr& operator=(const counted_ptr& p)
{
pointer = p.pointer;
count = p.count;
++*count;
return *this;
}
T* operator->() const{ return pointer; }
T& operator*() const { return *pointer; }
int Get_count() const { return *count; }
};
int main()
{
counted_ptr<double> one;
counted_ptr<double>two(one);
int a = one.Get_count();
cout << a << endl;
}
当我尝试做类似的事情时
one->pointer = new double(5);
,我收到一个编译器错误,提示“在 '*(&one)->counted_ptr::operator->with 中请求成员'指针'” T = double',属于非类类型 double”。
我考虑创建一个函数来执行此操作,虽然我可以创建一个函数来分配 T 数组,但我想不出一种方法来创建一个函数来分配实际对象。如有任何帮助,我们将不胜感激,谢谢。
I'm in the process of writing a smart pointer countedptr and I've hit a speed bump. The basic function of countedptr is to work like any other smart pointer and also have a count of how many pointers are pointing to a single object. So far, the code is:
[SOLVED]
#include "std_lib_facilities.h"
template <class T>
class counted_ptr{
private:
T* pointer;
int* count;
public:
counted_ptr(T* p = 0, int* c = new int(1)) : pointer(p), count(c) {} // default constructor
explicit counted_ptr(const counted_ptr& p) : pointer(p.pointer), count(p.count) { ++*count; } // copy constructor
~counted_ptr() { --*count; delete pointer; }
counted_ptr& operator=(const counted_ptr& p)
{
pointer = p.pointer;
count = p.count;
++*count;
return *this;
}
T* operator->() const{ return pointer; }
T& operator*() const { return *pointer; }
int Get_count() const { return *count; }
};
int main()
{
counted_ptr<double> one;
counted_ptr<double>two(one);
int a = one.Get_count();
cout << a << endl;
}
When I try to do something like
one->pointer = new double(5);
then I get a compiler error saying "request for member 'pointer' in '*(&one)->counted_ptr::operator->with T = double' which is of non-class type double".
I considered making a function to do this, and while I could make a function to allocate an array of T's, I can't think of a way of making one for allocating actual objects. Any help is appreciated, thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
旧的解决方案
另一个赋值运算符怎么样?
此外,您的析构函数总是删除共享指针,这可能是导致 *one 成为随机数的原因。也许您想要类似的东西:
新解决方案
当您想要重新指向 counted_ptr(例如
one = new double(5)
)以更新所有相关的counted_ptr
时,请将指针和帮助程序类中的计数,并让您的指针类保存指向该帮助程序类的指针(您可能已经沿着这条路径走下去)。您可以采用两种方法来完成此设计:使
counted_ptr
成为帮助程序类。counted_ptr
维护引用计数,但不会自动更新计数;它不是一个智能指针,它只响应release
和retain
消息。如果您完全熟悉 Objective-C,这基本上就是它的传统内存管理 (自动释放 放在一边)。当引用计数达到 0 时,counted_ptr
可能会也可能不会删除自身(与 Obj-C 的另一个潜在差异)。counted_ptr
不应被复制。其目的是,对于任何普通指针,最多应该有一个counted_ptr
。创建一个
smart_ptr
类,它有一个指向counted_ptr
的指针,该指针在应该保存相同 plain 的smart_ptr
实例之间共享指针。smart_ptr
负责通过发送其counted_ptr
释放和保留方法来自动更新计数。counted_ptr
可能是也可能不是shared_ptr
的私有内部类。这是选项二的界面。由于您将此作为练习,因此我将让您填写方法定义。潜在的实现与已经发布的类似,只是您不需要
counted_ptr
的复制构造函数和复制赋值运算符,counted_ptr::~counted_ptr
不会调用counted_ptr::release
(这是smart_ptr::~smart_ptr
的工作)并且counted_ptr::release
可能不会释放counted_ptr:: _pointer
(您可以将其留给析构函数)。希望以上唯一含糊之处是有意为之的。
Old Solution
What about another assignment operator?
Also, your destructor always deletes a shared pointer, which is probably what caused *one to be a random nomber. Perhaps you want something like:
New Solution
As you want repointing a counted_ptr (eg
one = new double(5)
) to update all relatedcounted_ptr
s, place both the pointer and the count in a helper class, and have your pointer class hold a pointer to the helper class (you might already be headed down this path). You could go two ways in filling out this design:Make
counted_ptr
the helper class.counted_ptr
maintains a reference count but doesn't automatically update the count; it's not a smart pointer, it only responds torelease
andretain
messages. If you're at all familiar with Objective-C, this is basically its traditional memory management (autoreleasing aside).counted_ptr
may or may not delete itself when the reference count reaches 0 (another potential difference from Obj-C).counted_ptr
s shouldn't be copyable. The intent is that for any plain pointer, there should be at most onecounted_ptr
.Create a
smart_ptr
class that has a pointer to acounted_ptr
, which is shared amongsmart_ptr
instances that are supposed to hold the same plain pointer.smart_ptr
is responsible for automatically updating the count by sending itscounted_ptr
release and retain methods.counted_ptr
may or may not be a private inner class ofshared_ptr
.Here's an interface for option two. Since you're doing this as an exercise, I'll let you fill out the method definitions. Potential implementations would be similar to what's already been posted except that you don't need a copy constructor and copy assignment operator for
counted_ptr
,counted_ptr::~counted_ptr
doesn't callcounted_ptr::release
(that'ssmart_ptr::~smart_ptr
's job) andcounted_ptr::release
might not freecounted_ptr::_pointer
(you might leave that up to the destructor).Hopefully, the only ambiguous points above are the intentional ones.
(抱歉,这里是新手,无法发表评论)。 Adatapost 添加的“
one=new double(5);
”应该可以工作。不过,还需要进行另一项更改:引用计数需要一点帮助。当然,这里有一些代码重复。将该代码重构为自己的函数可能是有意义的,例如
(Sorry, newbie here, and can't leave comments). What Adatapost added, "
one=new double(5);
" should work. One other change needed, though: the reference counting needs a little help.Of course, there's some code repetition here. It might make sense to refactor that code into its own function, e.g.
也许您的意思是“
one.pointer=new double(5);
”?写入“one->pointer=new double(5);
”会调用counted_ptr::operator->
。也就是说,它大约相当于:但双指针不是结构,因此它没有
pointer
成员。Did you, perhaps, mean "
one.pointer=new double(5);
"? Writing "one->pointer=new double(5);
" invokescounted_ptr<double>::operator->
. That is, it is approximately equivalent to:But a double pointer isn't a structure, and so it doesn't have a
pointer
member.由于眼前的问题已经解决,我想提供一些更长期的东西:
当您继续开发此代码时,您肯定会希望将其提供给经验丰富的程序员进行全面审查,无论是在这里还是其他地方。当您发布代码时,您的代码存在一些明显的问题,尽管 outis 已帮助纠正这些问题。但是,即使您的代码全部编译完毕并且似乎可以在您自己的测试中工作,也可能存在您尚未学会考虑的测试和情况。智能指针很容易出现微妙的问题,只有在非常特定的情况下才会出现。因此,您会希望其他人检查您的代码以查找您可能错过的任何内容。
请不要将此视为对您当前代码的任何形式的侮辱。我只是提供这个友好的建议,以确保您从这个项目中学到最多的东西。
Since the immediate problem has already been solved, I want to offer something more long term:
As you continue to develop this code, you'll definitely want to offer it up for full review by experienced programmers, whether here or elsewhere. There were a few obvious problems with your code as you posted it, though outis has helped correct them. But even once your code all compiles and seems to work in your own tests, there may be tests and situations which you haven't yet learned to think about. Smart pointers can easily have subtle problems that don't show up until very specific situations. So you'll want others to look over your code to find anything which you may have missed.
Please don't take this as any kind of insult towards your current code. I'm just offering this as friendly advice to ensure you learn the most you can out of this project.
除非您不是出于学术原因这样做,否则您可能需要考虑使用
use_count()
boost::shared_ptr
的成员。它并不完全有效,但它确实有效,并且您最好使用经过充分测试、成熟且线程安全的东西。如果您这样做是出于学习目的,请务必查看 更有效的 C++。Unless you are not doing this for academic reasons, you might want to use consider using the
use_count()
member ofboost::shared_ptr
. It's not entirely efficient, but it does work and you're better off using something well tested, mature, and thread safe. If you are doing this for learning purposes, be sure to check out the treatment of Reference Counting and Smart Pointers in More Effective C++.在覆盖之前,您需要递减计数并可能删除指向运算符 = 中旧值的指针。在有“删除指针”的地方还需要“删除计数”以避免内存泄漏
You need to decrement the count and possibly delete the pointer to the old value in operator = before you overwrite it. You also need 'delete count' everywhere you have 'delete pointer' to avoid leaking memory