2013-02-05 39 views
0

通过复制其他对象来创建新类时遇到了一些问题。从我可以看到,下面的代码工作,但是我的编译器指出它缺少类材料的默认构造函数。从我所看到的情况来看,这不是必需的。我在这里做错了什么?C++通过构造函数复制对象

第一类的构造函数:

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

请添加错误信息。当你错过一个默认的构造函数时,你的编译器的真实时间为99.999999%。通常,一个类将缺少的默认构造函数类作为成员,并且不会在类中正确初始化该成员。 –

+0

你能告诉我们'shadingBatch'的定义和它的构造函数的调用吗? –

+3

除非你真的需要,否则不要使用'new',并且你知道你在做什么。目前,这只是造成麻烦和资源泄漏。 – juanchopanza

回答

1

你在做什么不是构造对象,而是将它们的参数复制到内部对象后面它们已经被构建。你想查看初始化列表的概念。要实现这样看起来构造:

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

如果你不类成员明确在初始化列表初始化,它们将被默认的构造。或者至少,编译器会尝试。材料似乎没有默认的构造函数,所以编译器会在你的尝试中抱怨。

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

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_) {} 

(如果还有更多的事情要做,但你的想法可能更多的初始化代码)