0

他のオブジェクトをコピーして新しいクラスを作成する際にいくつか問題があります。私が見る限り、以下のコードは機能しますが、私のコンパイラは、クラス マテリアルのデフォルト コンストラクタがないと述べています。私が見ることができるものから、これは必要ありません。私はここで何か間違っていますか?

ファーストクラスのコンストラクター:

    shadingBatch::shadingBatch(const vertexAttribLayout& layout, const material& batchMaterial){
    dataFormat_ = layout;
    batchMaterial_ = *(new material(batchMaterial));
}

私も試してみました

shadingBatch::shadingBatch(const vertexAttribLayout& layout, const material& batchMaterial){
            dataFormat_ = layout;
            batchMaterial_ = batchMaterial;
        }

しかし、同じコンパイラ エラーが返されます。

セカンドクラスの定義

    class material {
protected:
    shader shader_;
public:
    material (const shader* shaderProgram);
    material (const material&);
    ~material();

    void compileShader();
} ;

2 番目のクラスのコピー コンストラクター

material::material(const material& other){
        shader_ = *(new shader(other.shader_));
    }

編集:要求されたように、

ファーストクラスの定義

class shadingBatch {
    friend class cheeseRenderer;
protected:
    std::vector<primitive*> primitives_;
    std::vector<vertex> vertices_;
    std::vector<GLuint> elements_;
    vertexAttribLayout dataFormat_;
    material batchMaterial_;
    GLuint VAO_;
    GLuint VBO_;
    GLuint EBO_;
public:
    ~shadingBatch();
    GLuint updateBatch (void);
    void addPrimitive (primitive*);
    shadingBatch(const vertexAttribLayout&, const material&);
private:
    void updatePrimitives (void);
    void setVertexAttributes(void);
} ;

そして、コンストラクターが呼び出される場所:

shader* defaultShader = new shader(fragmentSource,vertexSource);
material* defaultMaterial = new material(defaultShader);
vertexAttribLayout* defaultVertexData = new vertexAttribLayout();
shadingBatch* batch = new shadingBatch(*defaultVertexData,*defaultMaterial);
cheeseRenderer renderer(*batch);
4

2 に答える 2

4

まず、イニシャライザ リストを使用する必要があります。初期化子リストで明示的に初期化されていないメンバー変数オブジェクトは、コンストラクター本体が実行される前に呼び出されるデフォルトのコンストラクターを持ちます。次に、新しいことも行いますが、削除しないでください (ポインターを失うため)。そのため、コンストラクターでメモリ リークが発生します。これを試して:

shadingBatch::shadingBatch(const vertexAttribLayout& layout, 
                           const material& batchMaterial) :
    dataFormat_(layout)
   ,batchMaterial_(batchMaterial)
{
}

上記は、 と の両方が class のメンバー変数であるdataFormat_と想定しており、クラス定義ではその順序で宣言されているため、そうでない場合は必要に応じて修正してください。batchMaterial_shadingBatch


また、メモリリークmaterial::materialとデフォルトのコンストラクターの問題の両方があるため、次のようなものが必要です。

material::material(const material& other) : shader_(other.shader_) {}

(さらにやるべきことがある場合は、初期化コードが増える可能性がありますが、アイデアは得られます。)

于 2013-02-05T08:17:57.227 に答える
1

あなたがしているのは、オブジェクトの構築ではなく、内部オブジェクトが構築された後に引数を内部オブジェクトにコピーすることです。初期化リストの概念を調べたい。実装するコンストラクタは次のようになります。

shadingBatch::shadingBatch(const vertexAttribLayout& layout, const material& batchMaterial)
  : dataFormat_(layout), batchMaterial_(batchMaterial) // <-- initialization list
{}

クラスメンバーを初期化リストで明示的に初期化しない場合、それらはデフォルトで構築されます。または、少なくとも、コンパイラは試行します。マテリアルにはデフォルトのコンストラクターがないように見えるため、コンパイラーは両方の試みで不平を言います。

補足: 最初のコンストラクターの試行には別のエラー、メモリ リークがあります。オブジェクトを作成しnew、結果のポインターを保存も削除もしないため、そのメモリ (およびオブジェクト自体) は永久に失われます。

于 2013-02-05T08:19:43.690 に答える