Ton*_*ion 0 c++ pointers casting
在C++ for Windows中,我有一些对象工厂,它应该通过将指向对象的指针传递给Create函数并返回一个创建的对象来创建一系列Info对象.
void CreateInfoObject(AbstractInfo** info); // The creation function
Run Code Online (Sandbox Code Playgroud)
AbstractInfo是一个基类,我们有许多类型的Info对象派生.
我想我现在可以创建一个Info对象,如下所示:
MyInfoObject* InfoObj = NULL; // derived from AbstractInfo object
InfoFactory fc;
fc.CreateInfoObject(&InfoObj); // Now I want to get my initialized pointer back
Run Code Online (Sandbox Code Playgroud)
但它说不能做演员......有什么不对?
错误:无法从MyInfoObject**_ W64转换为AbstractInfo**
编辑:第一个答案提到界面很可怕,看不到谁在分配等等......我怎样才能改进?
让我们考虑一下可能的实现CreateInfoObject:
void InfoFactory::CreateInfoObject(AbstractInfo** info)
{
*info = new SuperInfo;
}
Run Code Online (Sandbox Code Playgroud)
现在,SuperInfo并MyInfoObject没有在共同的权利什么?
这就是为什么一般来说,禁止以下内容:
struct Base {};
struct D1: Base {};
struct D2: Base {};
int main(int argc, char* argv[])
{
Base** base = nullptr;
D1* d = nullptr;
base = d;
}
Run Code Online (Sandbox Code Playgroud)
因为它可以D1指向不相关的东西.
有几种解决方案:
// 1. Simple
AbstractInfo* info = nullptr;
fc.CreateInfoObject(info);
// 2. Better interface
std::unique_ptr<AbstractInfo> info = fc.CreateInfoObject();
Run Code Online (Sandbox Code Playgroud)
然后,如果您确切地知道您拥有,您实际上MyInfoObject可以使用:
MyInfoObject* myInfo = static_cast<MyInfoObject*>(info);
Run Code Online (Sandbox Code Playgroud)
或者如果您不确定:
MyInfoObject* myInfo = dynamic_cast<MyInfoObject*>(info);
Run Code Online (Sandbox Code Playgroud)
如果没有指向(或派生的)实例,将设置myInfo为.nullptrinfoMyInfoObject
但请记住,你的界面真的很可怕.它非常C-ish并且不清楚是否实际分配了内存......如果是,则负责处理内存.
编辑:
在良好的 C++风格中,我们使用RAII来表示所有权并确保清理.RAII虽然不是很有说服力,但我自己更喜欢新的SBRM(Scope Bound Resources Management).
这个想法是,不是使用一个没有指示所有权的裸指针(即你必须在其上调用delete吗?),你应该使用智能指针,例如unique_ptr.
您还可以使用方法的return参数,以避免进行两步初始化过程(首先创建指针,然后使其指向对象).这是一个简洁的例子:
typedef std::unique_ptr<AbstractInfo> AbstractInfoPtr;
// Note: if you know it returns a MyInfoObject
// you might as well return std::unique_ptr<MyInfoObject>
AbstractInfoPtr InfoFactory::CreateInfoObject()
{
return AbstractInfoPtr(new MyInfoObject());
}
// Usage:
int main(int argc, char* argv[])
{
InfoFactory factory;
AbstractInfoPtr info = factory.CreateInfoObject();
// do something
} // info goes out of scope, calling `delete` on its pointee
Run Code Online (Sandbox Code Playgroud)
在这里,所有权没有歧义.
另外,请注意您在此处更好地理解您的问题:
std::unique_ptr<MyInfoObject> info = factory.CreateInfoObject();
Run Code Online (Sandbox Code Playgroud)
不会编译,因为你不能使用或转换AbstractInfo*为a .MyInfoObject*static_castdynamic_cast