访问当前对象的类

时间:2015-11-14 23:15:41

标签: c++ c++11

我实施的virtual clone()方法可以完全相同,除了"实际"返回的对象的类型,我意识到会有很多重复。例如,这是我想要避免的明显解决方案:

AbstractVehicle* ConcreteCar::clone() const
{
    auto c = new ConcreteCar;
    c->setSomething(this->getSomething());
    return c;
}

AbstractVehicle* ConcreteJet::clone() const
{
    auto j = new ConcreteJet;
    j->setSomething(this->getSomething());
    return j;
}

这就是我想要的:

AbstractVehicle* AbstractVehicle::clone() const
{
    auto v = new this->ACTUAL_CLASS;
    v->setSomething(this->getSomething());
    return v;
}

有没有直接的方法来做到这一点?如果没有,我很想知道为什么会出现这种情况,因为天真地看起来实施起来并不像动态调度那样具有挑战性。

4 个答案:

答案 0 :(得分:2)

没有。 operator new要求在编译时指定要创建的对象的类型。你要求的是要求在编译时创建对象的类型是未知的,并在运行时计算出(或以其他方式获得)。

答案 1 :(得分:1)

没有直接的方法可以做到这一点。但是,(我可能因此而被绞死)您可以通过使用预处理器定义来避免编写clone函数的多个定义,如下所示:

#define DEFINE_VEHICLE_CLONE_MEMFUN(Vehicle) \
AbstractVehicle* Vehicle::clone() const {    \
    auto v = new Vehicle;                    \
    v->setSomething(this->getSomething());   \
    return v;                                \
}

然后在代码中将成员函数定义为:

DEFINE_VEHICLE_CLONE_MEMFUN(ConcreteCar)
DEFINE_VEHICLE_CLONE_MEMFUN(ConcreteJet)

答案 2 :(得分:1)

根据您定义的setSomething / getSomething函数的小时数,您可以保留单个克隆,并且只需覆盖“创建我”类型函数。例如:

AbstractVehicle* ConcreteCar::MakeNew() {    // virtual method
   return new ConcreteCar();
}

这将从基类clone中调用:

AbstractVehicle* AbstractVehicle::Clone() {
    auto j = MakeNew();
    j->setSomething(this->getSomething());
    return j;
}

答案 3 :(得分:0)

这可能不是你要求的;但这可能会实现你所追求的目标。我这里有一个抽象基类,有三个定义的派生类。我在类中没有一个虚拟类型的克隆方法,但我所拥有的是一个模板函数,可以为你工作。

var increment = $('#vehiclePhotoPreview' + photoID).width() + 10; //10 would be the space between each image

$('.vehicleDetailExpandedPhotoReel').scrollLeft(photoID * increment); //assuming that photoID is always sequential

另一个提醒是这个;模板函数和类通过new和delete运算符清理堆上的内存。因此需要谨慎使用这种方法或方法。如果想要实现类似的方法,但不必担心清理动态内存,那么应该在函数模板中使用智能指针。