C ++通过构造函数复制对象

时间:2013-02-05 08:14:01

标签: c++ class copy

通过将其他对象复制到新类来创建新类时遇到一些问题。从我所看到的,下面的代码工作,但我的编译器声明它缺少类材质的默认构造函数。从我所看到的,这是不需要的。我在这里做错了吗?

第一类构造函数:

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

第二类复制构造函数

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

2 个答案:

答案 0 :(得分:4)

首先,您应该使用初始化列表。在初始化程序列表中未显式初始化的任何成员变量对象将在执行构造函数体之前调用它的默认构造函数。然后你也做了新的,但从不删除它(因为你丢失了指针),所以你的构造函数泄漏了内存。试试这个:

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

上面假设dataFormat_batchMaterial_都是类shadingBatch的成员变量,并且它们在类定义中以该顺序声明,因此如果不是这样,则根据需要进行修复


你的material::material也有内存泄漏和默认构造函数问题,所以你需要这样的东西:

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

(如果还有更多的事情要做,可能会有更多的初始化代码,但你明白了。)

答案 1 :(得分:1)

您正在做的不是构造对象,而是在构造之后将参数复制到内部对象中。您想查找初始化列表的概念。您要实现的构造函数如下所示:

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

如果未在初始化列表中显式初始化类成员,则它们将是默认构造的。或者至少,编译器会尝试。材料似乎没有默认构造函数,因此编译器会在您的两次尝试中都抱怨。

旁注:第一个构造函数尝试有另一个错误,一个内存泄漏,因为你通过new创建一个对象,既不存储也不删除生成的指针,它的内存(和对象本身)将永远丢失。