C++ 可以使用void*指针进行静态_转换吗

C++ 可以使用void*指针进行静态_转换吗,c++,casting,C++,Casting,例如,建议maphhold其中void*总是存储classA中的指针,以后通过static\u cast将其回滚安全吗 classA* ptr = static_cast<classA*>( holditerator->second ); classA*ptr=static\u cast(holditerator->second); 之所以使用void*是因为hold是在某些cpp文件使用的头上定义的类的成员,这些文件不知道classA是什么。我必须在这些cpp文件中包含c

例如,建议
maphhold
其中
void*
总是存储
classA
中的指针,以后通过static\u cast将其回滚安全吗

classA* ptr = static_cast<classA*>( holditerator->second );
classA*ptr=static\u cast(holditerator->second);

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

是的,
静态强制转换在这种情况下是可以的,并且使用正确的方法

我不得不问你为什么不首先存储
classA*
指针。如果要将派生类指针放入其中,那么在将它们放入映射之前,需要将派生类指针向上投射/向上转换(隐式或显式地)到
classA*

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

之所以使用void*,是因为hold是一些不知道classA是什么的cpp文件使用的头上定义的类的成员

这可能是防止分层违规的有效理由

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


在你的情况下,这很可能是不必要的。提前声明就足够了。如果标头知道要放入映射中的内容,但只是想避免包含额外的标头,那么这就是解决方法

仅仅因为映射的用户不应该知道实际的类型,就在标题中写入void*不是一个好主意,因为您的代码中到处都会丢失类型安全性,包括知道ClassA的地方

考虑

  • 从代码的每一部分都可能知道的类派生ClassA
  • 将映射包装到一个对象中,该对象为代码中必须处理映射而不是ClassA的部分提供接口
  • 在头文件中声明但不定义类ClassA(如果在声明但未定义ClassA的某个位置销毁对象,可能会很危险)
  • 使用模板
  • 将包含映射的类实现为派生子类,以便将映射字段放入派生子类中
  • 第5点:插图(=模板图案)

    而不是

    class Containing {
        private:
           map<int,void*> myMap;
        public:
           void somePublicFunction () { // ...implementation }
    };
    
    包含{
    私人:
    地图我的地图;
    公众:
    void somePublicFunction(){/…实现}
    };
    
    你写

    // Containing.h
    class Containing {
       protected:
           virtual void doSomething () = 0;
       public:
           static Containing* Create ();
           void somePublicFunction () { doSomething (); }
           virtual ~Containing () { }
    };
    
    // Containing.cc
    #include ContainingImplementation.h
    Containing* Containing::Create () { return new ContainingImplementation; }
    
    // ContainingImplementation.h / cc
    class ContainingImplementation : public Containing {
       protected:
          virtual void doSomething () { // ... }
       private:
          map<int,ClassA*> myMap;
       public:
          virtual ~ContainingImplementation () { }
    };
    
    //包含.h
    类包含{
    受保护的:
    虚空剂量测量()=0;
    公众:
    静态包含*Create();
    void somePublicFunction(){doSomething();}
    虚拟~包含(){}
    };
    //包含.cc
    #包括ContainingImplementation.h
    Containing*Containing::Create(){returnnewcontainingimplementation;}
    //包含实现
    类ContainingImplementation:公共包含{
    受保护的:
    虚拟void doSomething(){/…}
    私人:
    地图我的地图;
    公众:
    虚拟~ContainingImplementation(){}
    };
    
    正如Johannes所解释的那样,
    静态演员阵容是可以的。防止cpp文件中对
    ClassA
    的依赖关系的另一种技术是使用

    //在头文件中
    B类{
    公众:
    类别b();
    ~classB();
    私人:
    类impl;
    独特的ptr pimpl;
    };
    //在实现文件中
    #包括“A类水电站”
    类B::impl
    {
    std::map hold;//隐藏在实现文件中
    };
    classB::classB():pimpl{new impl{/*…*/}}{}
    classB::~classB(){}
    
    您为什么要这样做?请提供更多的上下文,因为可能有更合适的解决方案。为什么不首先使用映射?@BatchyX我猜
    hold
    不仅仅包含classA*?您不能向前声明classA并使用classA指针吗?使用reinterpret\u cast会更好,因为它符合目的
    // 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() { }