static_cast是否可以使用void*指针

Vin*_*rta 6 c++ casting

例如,提出了map<int,void*>hold在那里void*总是存储指针从classA它安全通过的static_cast后投回来?

classA* ptr = static_cast<classA*>( holditerator->second );
Run Code Online (Sandbox Code Playgroud)

使用的原因void*是因为hold是某些cpp文件使用的标头上定义的类的成员,这些文件不知道是什么classA.我必须classA在这些cpp文件中包含定义的标题,这是由于许多原因无法完成的.

Joh*_*itb 13

是的,static_cast在这种情况下可以使用正确的东西.

我不得不问你为什么不在classA*第一时间存储指针.如果要将派生类指针放入其中,请注意,classA* 将它们放入映射之前,需要将派生类指针upcast/upconvert(隐式或显式).

但即使您将派生类指针放入映射中,基类指针也足够了,因为派生类指针可以隐式转换为基类指针.

使用void*的原因是因为hold是某些cpp文件所使用的标头上的类的成员,这些文件不知道classA是什么.

这可能是防止分层违规的正当理由.

我必须在这些cpp文件中包含classA定义的标头,这是由于许多原因无法完成的.

在您的情况下,这可能不是必需的.前瞻性声明就足够了.如果标题知道放入地图的内容,但只是想避免包含其他标题,那么这就是要走的路.


han*_*aad 6

正如约翰内斯所解释的那样,static_cast没关系.防止ClassAcpp文件中的依赖性的另一种技术是使用pimpl习语.

// in header file
class classB {
public:
    classB();
    ~classB();
private:
    class impl;
    unique_ptr<impl> pimpl;
};



// in implementation file
#include "classA.hpp"

class classB::impl 
{
    std::map<int, classA> hold;  // hidden in implementation file
};

classB::classB() : pimpl{ new impl{ /*...*/ } } { }
classB::~classB() { } 
Run Code Online (Sandbox Code Playgroud)