如何在 C++ 中正确地向下转换

Posted

技术标签:

【中文标题】如何在 C++ 中正确地向下转换【英文标题】:How to downcast properly in C++ 【发布时间】:2013-06-18 07:32:28 【问题描述】:

出于任何原因,我有一个由调用私有构造函数的静态方法创建的对象。 (不是单例)

我想从第一个派生一个新对象,它有更多的成员和功能。 但这是有问题的,因为静态方法返回一个firstObject* 对象,所以使用secondObject* 向下转换的创建会导致内存溢出。

我该怎么办?我可以访问第一个对象的代码,但无法更改它的构造函数(如果我更改它,我将不得不更改一个巨大的书面代码)。

编辑:

感谢所有响应者。我可以更改要保护的构造函数。

【问题讨论】:

发布代码比描述它更好。我不能完全从你的问题中找出问题所在。 将私有构造函数标记为受保护真的会导致必须重写那么多代码吗?然后以正常方式从中派生一个类。 如果您真的遇到内存溢出,那么问题出在其他地方。您的问题中没有任何内容与内存溢出有关。 请不要编辑您的问题以将其标记为已回答:要么接受一个正确答案,要么如果您不喜欢这些答案,请自己编写并接受。 @ereOn:你解决了他的问题,他在 16 分钟前忘记了你,而且还在数:)。 【参考方案1】:

确保您的构造函数至少为protected,以便子类可以使用它。

不知道你对内存溢出有什么担心,但是这个:

class Base 
public:
  static Base* getInstance();
  virtual ~Base() ;
protected:
  Base() ;
;

class Derived : public Base ;

// Implementation
Base* Base::getInstance()  return new Derived(); 

int main() 
Base::getInstance();
;

作品perfectly。

现在我建议您不要在这种情况下返回原始指针(std::unique_ptr 会更好)但这可能是题外话。

【讨论】:

这可能不起作用:基本构造函数是私有的。如果默认构造函数是公共的,就可以了。不过我们需要查看代码。 @Bathsheba:不错的收获。固定。 @ereOn;你确定编译吗?无法创建派生。 @ereOn 哦,我看到 Base() 受到保护。是的,这将编译。 @juanchopanza:不知道在答案中修正错字几分钟后重复第一条评论的意义何在。

以上是关于如何在 C++ 中正确地向下转换的主要内容,如果未能解决你的问题,请参考以下文章

C ++:如何遍历类类型列表以进行类型标识验证和向下转换?

如何正确地将 cv::Mat 转换为具有完美匹配值的 torch::Tensor?

如何正确地将这些转换为 c#,marshall,以便我可以将这些结构传递给 DLL (c++)?

如何正确检查是不是成功向下转换为 AnyObject?

为啥向下转换在 C++ 中是一种不好的做法,而不是在另一种语言中呢? [关闭]

如何在 C++ 中正确地在循环中使用互斥锁?