问题摘要 我不知道如何通过一个函数(而不是构造函数)用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
对象也在其创建的范围之外。
返回一个指针,从 func
可能是最好的选择,但如果你不能修改 func
然后 ptr = new Derived(func(args))
可能会起作用。这就要求 Derived
有一个复制构造函数或一个移动构造函数。
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();
};
你可能需要考虑把你的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); }
如果你想把它推广到任何兼容的类和参数类型。你可能还想对共享指针进行类型化定义,以获得更好的可读性.共享指针也会照顾到对象的寿命。
首先,感谢每一位回复的人。大家的建议来得非常快,而且非常有帮助和指导性。
我不知道这样做是否违反了某些惯例,但由于有多种非常不同的解决方案,我想总结一下。如果我应该把这个作为问题的编辑,请告诉我)。
这三种解决方案应该都可以,我现在用的是解决方案2。不过,在了解了更多关于智能指针的知识后,我可能会改用解决方案3。
改变功能 func
以便它返回一个指针。
Derived* func(args)
{
Derived *p = new Derived();
// do some complicated configuration
return p;
}
之后,我可以使用函数直接定义指针的 ptr
.
ptr = func(args);
亚历克斯还就如何删掉的问题提出了一些重要意见。ptr
后面。
虽然这很好用,但我选择不走这条路,因为我希望避免改变 func
.
使用复制构造函数。
这也许是最简单的解决方案。通过使用复制构造函数,我可以简单地写下
ptr = new Derived( func(args) );
虽然这需要一个copymove构造函数,但在我的项目中,它与默认的copy构造函数工作得非常好。我不需要实现任何新的东西。这就是目前我的代码中的解决方案。
使用智能指针,更具体地说就是一个 shared_ptr
(二者之一) std::shared_ptr
或 boost::shared_ptr
.) 这个概念对我来说是完全陌生的。谢谢你!我将更多地了解这一点,并可能改用这个选项。
我将更多地了解这一点,并可能切换到这个选项,因为它听起来像一个 清洁剂 的解决方案。如果我没有理解错的话,与其他两种解决方案相比,优势在于我不用考虑内存泄漏或删除指针的问题。一旦我想好了,我会回来扩展这个总结。