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() { }