制作一个适用于不完整类型的智能指针 [英] Making a smart pointer which works with incomplete types

查看:43
本文介绍了制作一个适用于不完整类型的智能指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很久以前在这个小组中问过如何制作一个智能指针

,它适用于不完整的类型。我得到了这个答案(只有相关的

部件包括):


// ----------------- -------------------------------------------------

模板< typename Data_t>

类SmartPointer

{

Data_t *数据;

void(* deleterFunc)(Data_t *);


static void deleter(Data_t * d){delete d; }


void decrementReferenceCount()

{

if(data)

{

//递减引用计数然后:

if(< reference count == 0>)

{

deleterFunc (数据);

}

}

}


公开:

SmartPointer(Data_t * d):data(d),deleterFunc(& deleter){}

~SmartPointer(){decrementReferenceCount(); }

//等......

};

// --------------- -------------------------------------------------- -


完成这样的操作后,只有在构造

智能指针时,模板类型才必须完成。当它被破坏,复制或分配时,它不需要完整。


那时困扰我的是指向删除函数

是类的成员变量,增加了它的大小。更糟糕的是,

相同类型的所有智能指针实例将具有与成员变量相同的功能指针,这感觉就像是一个巨大的浪费。


然后它发生在我身上:这个指针有什么原因不能是静态的吗?像这样:


// --------------------------------- ---------------------------------

template< typename Data_t>

类SmartPointer

{

....

static void(* deleterFunc)(Data_t *);

....

公开:

SmartPointer(Data_t * d):数据(d)

{

deleterFunc =& deleter;

}

....

};


模板< typename Data_t>

void(* SmartPointer< Data_t> :: deleterFunc)(Data_t *)= 0;

// ------ -------------------------------------------------- ----------


这样指向删除器的指针只会存储在程序中一次,最重要的是它不会增加智能

指针的大小。


现在我感觉非常明显,我真的很想知道为什么

这不是我的建议。在这里有一些错误我是否缺少



(将函数指针初始化为
$ b $似乎很危险b null,因为在某些情况下,dowmetReferenceCount()函数可能会在某个情况下调用该空指针。但是,只要''中有某些内容,就会发生
'data''指针,删除函数

指针总是被初始化。在这个

中,将函数指针作为成员变量没有什么不同。)

I asked a long time ago in this group how to make a smart pointer
which works with incomplete types. I got this answer (only relevant
parts included):

//------------------------------------------------------------------
template<typename Data_t>
class SmartPointer
{
Data_t* data;
void(*deleterFunc)(Data_t*);

static void deleter(Data_t* d) { delete d; }

void decrementReferenceCount()
{
if(data)
{
// decrement reference count and then:
if(<reference count == 0>)
{
deleterFunc(data);
}
}
}

public:
SmartPointer(Data_t* d): data(d), deleterFunc(&deleter) {}
~SmartPointer() { decrementReferenceCount(); }
// etc...
};
//------------------------------------------------------------------

When done like this, the template type must be complete only when the
smart pointer is constructed. It doesn''t need to be complete when it''s
destructed, copied or assigned.

What bothered me back then is that the pointer to the deleter function
is a member variable of the class, increasing its size. What is worse,
all the smart pointer instances of the same type will have the exact
same function pointer as member variable, which feels like a huge waste.

Then it occurred to me: Is there any reason this pointer cannot be
static? Like this:

//------------------------------------------------------------------
template<typename Data_t>
class SmartPointer
{
....
static void(*deleterFunc)(Data_t*);
....
public:
SmartPointer(Data_t* d): data(d)
{
deleterFunc = &deleter;
}
....
};

template<typename Data_t>
void(*SmartPointer<Data_t>::deleterFunc)(Data_t*) = 0;
//------------------------------------------------------------------

This way the pointer to the deleter will be stored in the program only
once, and most importantly it will not increment the size of the smart
pointer.

This feels so glaringly obvious to me now that I really wonder why
this wasn''t suggested to me to begin with. Is there some error here I''m
missing?

(It might seem hazardous to have the function pointer initialized to
null, as it might happen that the decremetReferenceCount() function
might in some situations make a call to that null pointer. However,
whenever there is something in the ''data'' pointer, the deleter function
pointer will always have been initialized. It''s no different in this
regard as having the function pointer as a member variable.)

推荐答案

Alf P. Steinbach写道:
Alf P. Steinbach wrote:

* Juha Nieminen:
* Juha Nieminen:

>我很久以前在这个小组中问过如何制作一个智能指针
,它适用于不完整的类型。我得到了这个答案(仅包括相关的部分):

// ------------------------- -----------------------------------------
template< typename Data_t>
类SmartPointer
{Data_t * data;
void(* deleterFunc)(Data_t *);

static void deleter(Data_t * d){删除d; }

void decrementReferenceCount()
{
if(data)
{
//减少引用计数然后:
if(< ;引用计数== 0>)
{
deleterFunc(数据);
}
}
}

公开: SmartPointer(Data_t * d):data(d),deleterFunc(& deleter){}
~SmartPointer(){decrementReferenceCount(); }
//等......
};
// --------------------------- ---------------------------------------

什么时候做的像这样,只有在构造
智能指针时,模板类型才必须完整。当它被破坏,复制或分配时,它不需要完整。

当时困扰我的是指向删除函数的指针
是类的成员变量,增加其大小。更糟糕的是,
相同类型的所有智能指针实例将具有与成员变量相同的功能指针,这感觉就像是一个巨大的浪费。

然后它发生了对我说:这个指针有什么原因不能静止吗?像这样:

// ------------------------------------- -----------------------------
模板< typename Data_t>
类SmartPointer
{
...
static void(* deleterFunc)(Data_t *);
...
公开:
SmartPointer(Data_t * d):data(d)
{
deleterFunc =& deleter;
}
...
};

模板< typename Data_t>
无效(* SmartPointer< Data_t> :: deleterFunc)(Data_t *)= 0;
// --------------------------- ---------------------------------------

这样的方式指向删除器的指针只会存储在程序中一次,最重要的是它不会增加智能指针的大小。

这对我来说非常明显现在,我真的好奇为什么
这不是建议我开始。这里有什么错误我很遗憾吗?
> I asked a long time ago in this group how to make a smart pointer
which works with incomplete types. I got this answer (only relevant
parts included):

//------------------------------------------------------------------
template<typename Data_t>
class SmartPointer
{
Data_t* data;
void(*deleterFunc)(Data_t*);

static void deleter(Data_t* d) { delete d; }

void decrementReferenceCount()
{
if(data)
{
// decrement reference count and then:
if(<reference count == 0>)
{
deleterFunc(data);
}
}
}

public:
SmartPointer(Data_t* d): data(d), deleterFunc(&deleter) {}
~SmartPointer() { decrementReferenceCount(); }
// etc...
};
//------------------------------------------------------------------

When done like this, the template type must be complete only when the
smart pointer is constructed. It doesn''t need to be complete when it''s
destructed, copied or assigned.

What bothered me back then is that the pointer to the deleter function
is a member variable of the class, increasing its size. What is worse,
all the smart pointer instances of the same type will have the exact
same function pointer as member variable, which feels like a huge waste.

Then it occurred to me: Is there any reason this pointer cannot be
static? Like this:

//------------------------------------------------------------------
template<typename Data_t>
class SmartPointer
{
...
static void(*deleterFunc)(Data_t*);
...
public:
SmartPointer(Data_t* d): data(d)
{
deleterFunc = &deleter;
}
...
};

template<typename Data_t>
void(*SmartPointer<Data_t>::deleterFunc)(Data_t *) = 0;
//------------------------------------------------------------------

This way the pointer to the deleter will be stored in the program only
once, and most importantly it will not increment the size of the smart
pointer.

This feels so glaringly obvious to me now that I really wonder why
this wasn''t suggested to me to begin with. Is there some error here I''m
missing?



是的。连续的智能指针实例化可以改变常见的

删除函数指针。


Yeah. Successive smart pointer instantiations can change the common
deleter func pointer.



[snip]


怎么样?


Best


Kai-Uwe Bux

[snip]

How?

Best

Kai-Uwe Bux


On 2008-09-07 08:00:48 -0400,Juha Nieminen< no **** @ thanks.invalidsaid:
On 2008-09-07 08:00:48 -0400, Juha Nieminen <no****@thanks.invalidsaid:

>

当时困扰我的是指向删除函数的指针

是类的成员变量,增加了它的大小。更糟糕的是,

相同类型的所有智能指针实例将具有与成员变量相同的功能指针,这感觉就像是一个巨大的浪费。


然后它发生在我身上:这个指针有什么原因不能是静态的吗?像这样:
>
What bothered me back then is that the pointer to the deleter function
is a member variable of the class, increasing its size. What is worse,
all the smart pointer instances of the same type will have the exact
same function pointer as member variable, which feels like a huge waste.

Then it occurred to me: Is there any reason this pointer cannot be
static? Like this:



TR1'的shared_ptr(基于Boost)将删除对象与参考一起放在

控制块中count和指向

托管资源的指针。删除器不属于该类型(即它不是

模板参数)。


-

Pete

Roundhouse Consulting,Ltd。( www.versatilecoding.com )作者

标准C ++库扩展:教程和参考
www.petebecker.com/tr1book )

TR1''s shared_ptr (based on Boost) puts the deleter object in the
control block, along with the reference count and the pointer to the
managed resource. The deleter is not part of the type (i.e. it''s not a
template argument).

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)


Alf P. Steinbach写道:
Alf P. Steinbach wrote:

* Kai-Uwe Bux:
* Kai-Uwe Bux:

> Alf P. Steinbach写道:
>Alf P. Steinbach wrote:

>> * Juha Nieminen:

然后它发生在我身上:这个指针有什么原因不能静止吗?像这样:

// ------------------------------------- -----------------------------
模板< typename Data_t>
类SmartPointer
{
...
static void(* deleterFunc)(Data_t *);
...
公开:
SmartPointer(Data_t * d):data(d)
{
deleterFunc =& deleter;
}
...
};

模板< typename Data_t>
无效(* SmartPointer< Data_t> :: deleterFunc)(Data_t *)= 0;
// --------------------------- ---------------------------------------

这样的方式指向删除器的指针只会存储在程序中一次,最重要的是它不会增加智能指针的大小。

这感觉如此现在我很明显,我真的很想知道为什么我不建议开始这样做。这里有什么错误我很遗憾吗?
是的。连续的智能指针实例化可以改变常见的删除函数指针。
>>* Juha Nieminen:

Then it occurred to me: Is there any reason this pointer cannot be
static? Like this:

//------------------------------------------------------------------
template<typename Data_t>
class SmartPointer
{
...
static void(*deleterFunc)(Data_t*);
...
public:
SmartPointer(Data_t* d): data(d)
{
deleterFunc = &deleter;
}
...
};

template<typename Data_t>
void(*SmartPointer<Data_t>::deleterFunc)(Data_t *) = 0;
//------------------------------------------------------------------

This way the pointer to the deleter will be stored in the program
only
once, and most importantly it will not increment the size of the smart
pointer.

This feels so glaringly obvious to me now that I really wonder why
this wasn''t suggested to me to begin with. Is there some error here I''m
missing?
Yeah. Successive smart pointer instantiations can change the common
deleter func pointer.


[snip]

怎么样?

[snip]

How?



对不起,我对静态指针做出了反应。正如我所写,使用模板

参数代替。指向

函数的唯一有效原因是更改指针,这显然是在

构造函数体中完成的,


Sorry, I reacted to the static pointer. As I wrote use a template
parameter instead. The only valid reason for having a pointer to that
function is to change the pointer, and that''s apparently done in the
constructor body,



真的吗?然后一个智能指针使用不完整类型(在某种意义上

上面)要么没有资格作为一个有效的理由,或者必须有一个方法

没有那个(静态)指针。这是什么?如果它是第二个,那么

使智能指针与不完整类型一起工作的方式你有吗?

介意吗?

Really? Then a smart pointer working with incomplete types (in the sense
above) either does not qualify as a valid reason or there must be a way
without that (static) pointer. Which is it? and if it is the second, which
way of making a smart pointer work with incomplete types do you have in
mind?


所以我读取构造函数参数作为指向func的指针

(没有真正读过它,我只推断出唯一可以做的事情

感觉,假设代码是明智的。


正如我所写,使用模板参数。


静态指针不会感觉,并且在
中有一个荒谬的事情导致像我这样的人对代码得出错误的结论

(我们实际上没有看过它,我们只看一看它就像一个擅长

国际象棋的人可能会看到一个随机生成的国际象棋位置,并认为它是明智的并得出错误的结论。
so I read the constructor argument as pointer to func
(didn''t really read it, I only inferred the only thing that could make
sense, assuming the code was sensible).

As I wrote, use a template parameter.

The static pointer doesn''t make sense, and having a nonsensical thing in
there causes people like me to draw incorrect conclusions about the code
(we don''t actually read it, we just look at it, like e.g. someone good at
chess might look at a randomly generated chess position and assume that
it''s sensible and draw wrong conclusions).



只要关于不完整类型的问题没有解决,我将推迟判断所提供的代码是否为b $ b荒谬与否。

Best


Kai-Uwe Bux

As long as the issue about incomplete types is not out of the way, I will
defer judgement as to whether the code presented is nonsensical or not.
Best

Kai-Uwe Bux


这篇关于制作一个适用于不完整类型的智能指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆