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

「これ」に割り当てることはできません。const型です。

クラス型 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

私は他のほとんどの答えに同意しますが、あなたの場合、古典的なファクトリーパターンは必要ありません。おわかりのように、形状のパラメトリック関数を使用して形状を記述する単一のクラスが必要です。「ドーナツ」などの特殊なケースのために、これらの形状を作成するための便利なメソッドを提供したいと考えています。特殊な形状タイプのメソッドをオーバーロードするなど、他の継承機能を使用したくない場合は、他のクラスを削除Donutして、クライアント コードで "maker" 関数を使用するだけでかまいません。

コードをよりオブジェクト指向に見えるようにするオプション (およびサブクラスを保持し、クライアント コードでそれらのコンストラクターを使用するオプション) として、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 に答える
0

はい、可能です... :)

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

コピーコンストラクターが定義されていることを確認し、 this->~Donut();デフォルトのコンストラクターを介して割り当てられたすべてが削除されるようにし、2行目でnew (this) ( (Donut*) ParametricShape::makeDonut(1.0f) );最初にドーナツオブジェクトを作成し、それをドーナツとして再解釈します[注意してください、ドーナツは変数を定義していないため、ここでは問題ありません親より]そしてコピーコンストラクターを呼び出します...

new (this) はメモリから新しいストレージを割り当てず、コンストラクターを呼び出すだけです:)

于 2012-12-06T19:10:06.740 に答える