在子类中重用工厂类型构造函数

时间:2012-12-06 18:54:59

标签: c++ factory copy-constructor

抱歉,我很喜欢C ++这种可能吗?

我有一个具有巨大构造函数的超类,所以我创建了一个静态工厂类型构造函数,它将执行一些工作,然后返回新的ParametricShape(等等等等等等);

class ParametricShape: public ModelView{

public:
    //actually has 15 arguments didn't want to type them all up
    ParametricShape(func x, funcy, funcz, float lu, float hu, float lv, float hv, int sv, int su);

     static ParametricShape* makeDonutShape(float);
 }

后来我想在扩展类中使用这个静态方法。

class Donut : public ParametricShape{
    Donut();
}

Donut::Donut(){
  this = ParametricShape::makeDonut(1.0f);
}

这是我正在尝试做的事情,我一直在摸索各种副本构造函数,什么不是,并且已经得到各种不同的错误。目前它只是说:lvalue需要作为左操作数的赋值。谢谢你的帮助!

4 个答案:

答案 0 :(得分:2)

您无法指定“此”。它是一种常量类型。

  

The type of the this pointer for a member function of a class type X, is X* const.

在工厂设计模式中,您通常会有一个单独的类来负责创建新实例。对象创建与类它的分离是这个设计模式的重点。 See this discussion on how to implement this in C++

答案 1 :(得分:1)

这是典型的"工厂"图案:

#include <memory>

struct Shape
{
    enum Type { Donut, Sphere, Teapot };

    static std::unqiue_ptr<Shape> make(Type type);

    virtual ~Shape() = default;

    // ...
};

struct Donut : Shape
{
    // ...
};

std::unique_ptr<Shape> Shape::make(Shape::Type type)
{
    switch(type)
    {
        case Donut: return { new Donut; }
        default:    return { };
    }
}

用法:

auto p = Shape::make(Shape::Donut);

答案 2 :(得分:0)

是的,有可能......:)

#include <new>
Donut::Donut() {
    this->~Donut();
    new (this) ( *((Donut*) ParametricShape::makeDonut(1.0f)) );
}

确保定义了复制构造函数, this->~Donut();确保删除通过默认构造器分配的所有内容,并且第二行new (this) ( (Donut*) ParametricShape::makeDonut(1.0f) );首先创建一个甜甜圈对象,将其重新解释为Donut [小心,这在这里没有问题,因为Donut没有定义任何变量更多而不是它的父]并调用复制构造函数......

new(this)不会从内存中分配任何新存储,它只是调用构造函数:)

答案 3 :(得分:0)

虽然我同意大多数其他答案,但在您的情况下,您不需要经典的工厂模式。正如我所看到的,您希望有一个类来描述具有几何参数函数的形状。您希望提供方便的方法来为某些特殊情况创建这些形状,例如“甜甜圈”。只要您不想使用任何其他继承功能(如重载特殊形状类型的某些方法),您可以简单地删除其他类,如Donut,并在客户端代码中使用“maker”函数

使代码看起来更加面向对象的选项(并保留子类并在客户端代码中使用它们的构造函数),您可以将制造商函数重写为初始化函数,因为我想调用它们。请注意,我还在专门的类中引入了一个默认构造函数:

class ParametricShape {
    func x, y, z;
    ...

public:
    ParametricShape();
    ParametricShape(func x, func y, func z, ...);

protected:
    void initDonutShape(float);
};


class Donut : public ParametricShape {

public:
    Donut(float radius) :
        ParametricShape()         // call default constructor of ParametricShape
    {
        initDonutShape(radius);   // initialize functions for "Donut"
    }
};

现在,实现initDonutShape方法,如下所示:

void ParametricShape::initDonutShape(float radius) {
    // set the parametric functions
    x = ...
    y = ...
    z = ...
}

而不是返回ParametricShape的新实例。