0

抱歉,我对 C++ 很陌生,这种事情可能吗?

我有一个超类,它有一个巨大的构造函数,所以我创建了一个静态工厂类型构造函数,它会做一些工作,然后返回 new ParametricShape(blah blah blah...);

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);
}

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

4

4 回答 4

2

您不能分配给“this”。它是一个常量类型。

类类型 X 的成员函数的 this 指针的类型是 X* const。

在工厂设计模式中,您通常有一个单独的类来负责创建新实例。这种对象创建与类的分离是这个设计模式的重点。请参阅有关如何在 C++ 中实现这一点的讨论

于 2012-12-06T19:08:15.003 回答
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);
于 2012-12-06T19:08:39.017 回答
0

是的,有可能... :)

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

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

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

于 2012-12-06T19:10:06.740 回答
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.

于 2012-12-06T19:17:47.840 回答