Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 空洞指针的相关性_C++_Refactoring - Fatal编程技术网

C++ 空洞指针的相关性

C++ 空洞指针的相关性,c++,refactoring,C++,Refactoring,通过查看同事的代码,我看到它的一些句柄存储为空指针 // Class header void* hSomeSdk; // Class implementation hSomeSdk = new SomeSDK(...); ((SomeSDK*)hSomeSdk)->DoSomeWork(); 现在我知道,有时候句柄是空指针,因为在运行之前可能不知道句柄的实际类型。或者,当我们需要共享指针而不显示其实际结构时,它会有所帮助。但在我的情况下,情况似乎并非如此:它将始终是SomeSDK,并且

通过查看同事的代码,我看到它的一些句柄存储为空指针

// Class header
void* hSomeSdk;

// Class implementation
hSomeSdk = new SomeSDK(...);
((SomeSDK*)hSomeSdk)->DoSomeWork();
现在我知道,有时候句柄是空指针,因为在运行之前可能不知道句柄的实际类型。或者,当我们需要共享指针而不显示其实际结构时,它会有所帮助。但在我的情况下,情况似乎并非如此:它将始终是SomeSDK,并且不会在创建它的类之外共享。此外,该代码的作者已离开该公司

有没有其他原因可以解释为什么它是一个空指针?

没有

如果我不得不猜测的话,这位前同事不熟悉转发声明,因此不知道他们仍然可以在标题中执行
SomeSDK*
,而不包括整个
SomeSDK
定义

考虑到您提到的约束条件,此模式实现的唯一功能是消除某些类型安全性,使代码更难读取/维护,并生成堆栈溢出问题。

如果我不得不猜测的话,这位前同事不熟悉转发声明,因此不知道他们仍然可以在标题中执行
SomeSDK*
,而不包括整个
SomeSDK
定义


考虑到您提到的约束,此模式实现的唯一一件事是消除某些类型安全性,使代码更难读取/维护,并生成堆栈溢出问题。

由于这是一个成员变量,我要冒险说,您的同事希望最小化依赖关系。仅为了定义指针,可能不希望包含
SomeSDK
的头。从您展示的代码中我可以看出,这位同事可能有两个原因之一:

  • 他们只是不知道他们可以添加一个转发声明,比如
    classsomesdk以允许定义指针。一些程序员只是没有意识到这一点
  • 他们不能向前申报。如果
    SomeSDK
    不是一个类,而是一个类型别名(aka
    typedef
    ),那么就不可能准确地向前声明它。我们只能声明它的别名类,但这可能是一个很难跟踪的实现细节。即使是标准库也有类似的问题,这就是为什么它提供了使前向声明标准流类型更容易的功能

  • 如果代码中充满了这个句柄的类型转换,那么设计应该在很久以前就被修改过了。否则,如果它只在一个地方(或最多几个地方),我就能明白为什么维护它的人们可以和平地生活在一起

    因为这是一个成员变量,所以我想说你的同事希望最小化依赖关系。仅为了定义指针,可能不希望包含
    SomeSDK
    的头。从您展示的代码中我可以看出,这位同事可能有两个原因之一:

  • 他们只是不知道他们可以添加一个转发声明,比如
    classsomesdk以允许定义指针。一些程序员只是没有意识到这一点
  • 他们不能向前申报。如果
    SomeSDK
    不是一个类,而是一个类型别名(aka
    typedef
    ),那么就不可能准确地向前声明它。我们只能声明它的别名类,但这可能是一个很难跟踪的实现细节。即使是标准库也有类似的问题,这就是为什么它提供了使前向声明标准流类型更容易的功能

  • 如果代码中充满了这个句柄的类型转换,那么设计应该在很久以前就被修改过了。否则,如果它只在一个地方(或最多几个地方),我就能明白为什么维护它的人们可以和平地生活在一起

    void*
    在C语言中很流行,并且很需要。它们很方便,因为它们可以很容易地转换成任何东西。如果您需要从
    double*
    转换到
    char*
    ,则必须进行中间转换到
    void*

    void*
    的问题在于它们太灵活了:它们不能传达作者的意图,这使得它们非常不安全,尤其是在大型项目中

    在面向对象设计中,创建抽象接口类(所有成员都是虚拟的,没有实现)并指向这些类,然后根据使用情况实例化各种可能的实现是很流行的


    然而,现在更推荐使用模板(C++优于其他语言的主要优点),因为这些模板比OOD允许更快,并且能够使编译时间优化。不幸的是,使用模板仍然是一个巨大的麻烦-它们有更复杂的语法,并且很难向用户传达编写者关于模板参数的限制和要求的意图(解决问题的概念TS将在C++ 20中可用)——目前只有Sfaya,这是20年前的一个可怕的临时解决方案;而反射TS,它将大大增强C++中的泛型编程,即使在C++ 23中也不太可能使用。.

    void*
    在C语言中很流行,需要使用。它们很方便,因为它们可以轻松转换为任何内容。如果需要从
    double*
    转换为
    char*
    ,则必须进行中间转换到
    void*

    void*
    的问题在于它们太灵活了:它们不能传达作者的意图,这使得它们非常不安全,尤其是在大型项目中

    在面向对象设计中,创建抽象接口类(所有成员都是虚拟的,没有实现)并指向这些类,然后根据使用情况实例化各种可能的实现是很流行的

    但是,现在更推荐使用模板(C++的主要优点,而不是其他语言),因为这些模板更快,更容易实现。