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
不是一个类,而是一个类型别名(akatypedef
),那么就不可能准确地向前声明它。我们只能声明它的别名类,但这可能是一个很难跟踪的实现细节。即使是标准库也有类似的问题,这就是为什么它提供了使前向声明标准流类型更容易的功能如果代码中充满了这个句柄的类型转换,那么设计应该在很久以前就被修改过了。否则,如果它只在一个地方(或最多几个地方),我就能明白为什么维护它的人们可以和平地生活在一起 因为这是一个成员变量,所以我想说你的同事希望最小化依赖关系。仅为了定义指针,可能不希望包含
SomeSDK
的头。从您展示的代码中我可以看出,这位同事可能有两个原因之一:
classsomesdk代码>以允许定义指针。一些程序员只是没有意识到这一点
SomeSDK
不是一个类,而是一个类型别名(akatypedef
),那么就不可能准确地向前声明它。我们只能声明它的别名类,但这可能是一个很难跟踪的实现细节。即使是标准库也有类似的问题,这就是为什么它提供了使前向声明标准流类型更容易的功能如果代码中充满了这个句柄的类型转换,那么设计应该在很久以前就被修改过了。否则,如果它只在一个地方(或最多几个地方),我就能明白为什么维护它的人们可以和平地生活在一起
void*
在C语言中很流行,并且很需要。它们很方便,因为它们可以很容易地转换成任何东西。如果您需要从double*
转换到char*
,则必须进行中间转换到void*
void*
的问题在于它们太灵活了:它们不能传达作者的意图,这使得它们非常不安全,尤其是在大型项目中
在面向对象设计中,创建抽象接口类(所有成员都是虚拟的,没有实现)并指向这些类,然后根据使用情况实例化各种可能的实现是很流行的
然而,现在更推荐使用模板(C++优于其他语言的主要优点),因为这些模板比OOD允许更快,并且能够使编译时间优化。不幸的是,使用模板仍然是一个巨大的麻烦-它们有更复杂的语法,并且很难向用户传达编写者关于模板参数的限制和要求的意图(解决问题的概念TS将在C++ 20中可用)——目前只有Sfaya,这是20年前的一个可怕的临时解决方案;而反射TS,它将大大增强C++中的泛型编程,即使在C++ 23中也不太可能使用。.
void*
在C语言中很流行,需要使用。它们很方便,因为它们可以轻松转换为任何内容。如果需要从double*
转换为char*
,则必须进行中间转换到void*
void*
的问题在于它们太灵活了:它们不能传达作者的意图,这使得它们非常不安全,尤其是在大型项目中
在面向对象设计中,创建抽象接口类(所有成员都是虚拟的,没有实现)并指向这些类,然后根据使用情况实例化各种可能的实现是很流行的
但是,现在更推荐使用模板(C++的主要优点,而不是其他语言),因为这些模板更快,更容易实现。