返回指向对象的参数指针

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**

编辑:第一个答案提到界面很可怕,看不到谁在分配等等......我怎样才能改进?

Mat*_* M. 8

让我们考虑一下可能的实现CreateInfoObject:

void InfoFactory::CreateInfoObject(AbstractInfo** info)
{
  *info = new SuperInfo;
}
Run Code Online (Sandbox Code Playgroud)

现在,SuperInfoMyInfoObject没有在共同的权利什么?

这就是为什么一般来说,禁止以下内容:

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