加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 编写更通用的指针代码

发布时间:2020-12-16 03:46:21 所属栏目:百科 来源:网络整理
导读:假设我想编写一个接收指针的函数.但是我想允许调用者使用裸指针或智能指针 – 无论他们喜欢什么.这应该是好的,因为我的代码应该依赖于指针语义,而不是指针实际实现的方式.这是一种方法: templatetypename MyPtrvoid doSomething(MyPtr p){ //store pointer
假设我想编写一个接收指针的函数.但是我想允许调用者使用裸指针或智能指针 – 无论他们喜欢什么.这应该是好的,因为我的代码应该依赖于指针语义,而不是指针实际实现的方式.这是一种方法:
template<typename MyPtr>
void doSomething(MyPtr p)
{
    //store pointer for later use
    this->var1 = p;

    //do something here
}

上面将使用duck typing并且可以传递裸指针或智能指针.当传递的值是基指针时我们需要查看是否可以转换为派生类型.

template<typename BasePtr,typename DerivedPtr>
void doSomething(BasePtr b)
{
    auto d = dynamic_cast<DerivedPtr>(b);
    if (d) {
        this->var1 = d;

        //do some more things here
    }
}

上面的代码适用于原始指针,但不适用于智能指针,因为我需要使用dynamic_pointer_cast而不是dynamic_cast.

上面问题的一个解决方案是我添加了一个新的实用工具方法,例如universal_dynamic_cast,它通过使用std :: enable_if选择重载版本,对原始指针和智能指针都有效.

我的问题是,

>添加所有这些复杂性是否有价值,因此代码支持原始指针和智能指针?或者我们应该在库公共API中使用shared_ptr吗?我知道这取决于库的目的,但是在整个API签名中使用shared_ptr的一般感觉是什么?假设我们只需要支持C 11.
>为什么STL没有内置指针强制转换,无论你是否传递原始指针或智能指针?这是故意的STL设计师还是只是疏忽?
>上述方法中的另一个问题是智能感知的丢失和可读性的缺失.这显然是所有鸭类型代码中的问题.但是,在C中,我们有一个选择.我可以很容易地在上面输入我的论点,如shared_ptr< MyBase>这会牺牲灵活性,让调用者能够传递包含在任何指针中的任何东西,但是我的代码的读者会更自信,并且可以在应该进入的内容上构建更好的模型.在C公共库API中,是否有一般的偏好/优势或者另一个?
>我在其他SO答案中看到了另一种方法,作者提出你应该只使用模板< typename T>并让调用者决定T是否是某种指针类型或引用或类.如果我必须在T中调用某些东西,这种超级通用方法显然不起作用,因为C需要解除引用指针类型,这意味着我必须使用std :: enable_if将07运算符应用于指针类型,但对普通对象不执行任何操作.我想知道是否有任何设计模式可以更容易地实现这种超级通用方法.最重要的是,是否值得去解决所有这些问题,或者只是保持简单并在任何地方使用shared_ptr?

解决方法

在类中存储shared_ptr具有语义含义.这意味着该类现在声称拥有该对象的所有权:其破坏的责任.对于shared_ptr,您可能会与其他代码共享该职责.

存储一个裸体T * ……好,没有明确的含义. Core C指南告诉我们,裸指针不应该用于表示对象所有权,而是其他人做不同的事情.

根据核心指南,您所谈论的是根据用户如何调用对象,可能会或可能不会声明对象的所有权.我会说你的界面非常混乱.所有权语义通常是代码基本结构的一部分.一个功能要么拥有所有权,要么不拥有;它不是根据它被调用的地方来确定的.

但是,有时(通常出于优化原因)您可能需要这样做.你可能有一个对象,在一个实例中给予内存的所有权,而在另一个实例中则没有.这通常会产生字符串,其中一些用户将分配一个您应该清理的字符串,而其他用户将从静态数据(如文字)中获取字符串,因此您不需要清理它.

在这些情况下,我会说你应该开发一个具有这种特定语义的智能指针类型.它可以由shared_ptr< T>构成.或*.在内部,它可能使用变体< shared_ptr< T>,T *>或者类似的类型,如果您无权访问变体.

然后,您可以为其提供自己的动态/静态/重新解释/ const_pointer_cast函数,这些函数将根据内部变量的状态根据需要转发操作.

或者,可以为shared_ptr实例指定一个不执行任何操作的删除对象.因此,如果您的界面只使用shared_ptr,则用户可以选择传递技术上并非真正拥有的对象.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读