如何使用函数(而不是构造函数)将派生类对象分配给基类指针?

问题描述 投票:0回答:1

问题摘要 我不知道如何通过一个函数(而不是构造函数)用new-operator创建一个派生类的对象,并让基类指针指向它。

设置 我的项目中有一个抽象的基类和一个派生类。

class Base
{
    // stuff
};

class Derived : public Base
{
    //stuff
    //constructor:
    Derived(args);
};

我也有一个函数,返回一个 Derived 对象。

Derived func(args);

在某些时候,我声明一个基类指针

Base* ptr = { nullptr };

我想让它指向一个 Derived 对象以后。

我想要的 我想创建一个 Derived 使用 func的指针来访问它。ptr 后面的代码中。

到目前为止,我所做的 我知道,使用派生类的构造函数是可行的。

ptr = new Derived(args);

或者干脆就是它的默认构造函数,如果存在的话。

ptr = new Derived;

但是,我有充分的理由在我的情况下不能使用构造函数,因为派生对象的配置比较复杂。在这种情况下,我想使用函数 func.

我知道,这。

ptr = new func(args);

不起作用,因为 new 期待一个类型。如何才能实现这样的行为?

先谢谢大家的建议和有用的回复。

请注意。 我使用的是 new 因为我需要访问 Derived 对象也在其创建的范围之外。

c++ pointers inheritance derived-class base-class
1个回答
1
投票

返回一个指针,从 func 可能是最好的选择,但如果你不能修改 func 然后 ptr = new Derived(func(args)) 可能会起作用。这就要求 Derived 有一个复制构造函数或一个移动构造函数。


1
投票
Derived * func(args)
{
  Derived *p = new Derived();
  // do your custom stuff:
  p->x = args->i;
  p->y = 3;

  // return the pointer
  return p;
}

// ...

ptr = func(args);

不要忘记以后删除ptr。为了能够调用Derived的destructor,使用后面指向Base的指针,你必须使destructor虚拟化。

class Base
{
  // ...
  virtual ~Base();
};

0
投票

你可能需要考虑把你的func写成

template<class T, class TA> boost::shared_ptr<T> func(TA args) { return boost::make_shared<T>(args); }

template<class T, class TA> std::shared_ptr<T> func(TA args) { return std::make_shared<T>(args); }

如果你想把它推广到任何兼容的类和参数类型。你可能还想对共享指针进行类型化定义,以获得更好的可读性.共享指针也会照顾到对象的寿命。


0
投票

解决方案总结

首先,感谢每一位回复的人。大家的建议来得非常快,而且非常有帮助和指导性。

我不知道这样做是否违反了某些惯例,但由于有多种非常不同的解决方案,我想总结一下。如果我应该把这个作为问题的编辑,请告诉我)。

这三种解决方案应该都可以,我现在用的是解决方案2。不过,在了解了更多关于智能指针的知识后,我可能会改用解决方案3。

解决方案1--由 亚历克斯Daniel Langr

[答复链接]

改变功能 func 以便它返回一个指针。

Derived* func(args)
{
    Derived *p = new Derived();
    // do some complicated configuration
    return p;
}

之后,我可以使用函数直接定义指针的 ptr.

ptr = func(args);

亚历克斯还就如何删掉的问题提出了一些重要意见。ptr 后面。

虽然这很好用,但我选择不走这条路,因为我希望避免改变 func.

解决办法2----------由 Mestkorn

[答复链接]

使用复制构造函数。

这也许是最简单的解决方案。通过使用复制构造函数,我可以简单地写下

    ptr = new Derived( func(args) );

虽然这需要一个copymove构造函数,但在我的项目中,它与默认的copy构造函数工作得非常好。我不需要实现任何新的东西。这就是目前我的代码中的解决方案。

解决方案3 - 通过 DNT

[答复链接]

使用智能指针,更具体地说就是一个 shared_ptr (二者之一) std::shared_ptrboost::shared_ptr.) 这个概念对我来说是完全陌生的。谢谢你!我将更多地了解这一点,并可能改用这个选项。

我将更多地了解这一点,并可能切换到这个选项,因为它听起来像一个 清洁剂 的解决方案。如果我没有理解错的话,与其他两种解决方案相比,优势在于我不用考虑内存泄漏或删除指针的问题。一旦我想好了,我会回来扩展这个总结。

© www.soinside.com 2019 - 2024. All rights reserved.