无法实例化包含用户定义类型

时间:2015-12-17 21:18:02

标签: c++

我对Java有着深刻的理解,但我正在尝试学习c ++来制作游戏,因为我认为c ++是一种更好的语言。但我在使用c ++时遇到了一些问题。

#ifndef RENDER_H
#define RENDER_H

#include "shader.h"
class Render
{

public: 
    Render();
protected:
private:
    Shader shader;
};

#endif

Shader是一个带有字符串构造函数的类,只是在这个类中声明它会导致错误。如果我删除Shader的构造函数,我不会收到错误。

Error: render.cpp:3:16: error: no matching function for call to 'Shader::Shader()'

class Shader
{
public:
  Shader(const std::string& fileName);
  void Bind();
  void Update(const Transform& transform, const Camera& camera);

virtual ~Shader();

4 个答案:

答案 0 :(得分:3)

shaderRender的班级成员。在实例化Render对象时,需要在此过程中构造Shader对象。由于它没有提供默认的c,因此无法构造(错误消息告诉你的内容)。

要解决此问题,请为Shader 1)提供默认c,或使用Render s c的初始化列表:

Render::Render() : shader("foo") {}

Render::Render(const std::string& shaderFilename) : shader(shaderFilename) {}

<小时/> 1) 注意:如果没有定义任何c,则编译器会生成一个默认的c&#t; tor。这就是为什么要删除Shader自定义c来解决此问题的原因。

答案 1 :(得分:1)

您的问题出在Render构造函数中(未在问题中显示)。因为您的类Render有一个成员变量Shader,它只有一个构造函数(带有std::string参数),所以必须在构造函数中显式调用该构造函数初始化列表:

Render::Render()
: shader("MyRenderShader"); // construct the Shader
{
}
  

如果我删除了Shader的构造函数,我就不会收到错误。

请注意,当您删除Shader构造函数时,编译器会generates a default constructor for you,这意味着您不需要在Render中显式调用构造函数(尽管您应该)。< / p>

答案 2 :(得分:0)

这是您的描述

  

Shader是一个带有字符串构造函数的类,只是在其中声明它   class导致错误。如果我删除Shader的构造函数,我不会   得到错误

描述了这个问题。如果未在构造函数Render的mem-initializer列表中显式调用类Shader的构造函数,则编译器会尝试调用数据成员Shader shader;的默认构造函数。但是它没有声明,编译器发出错误。

在构造函数的mem-initializer列表中调用类Shader的构造函数Render指定参数或定义类Shader的默认构造函数。

答案 3 :(得分:0)

很可能你没有在Render构造函数中为Shader构造函数提供字符串。你渲染构造函数需要做这样的事情:

Render::Render()
   : shader("This is the string parameter of the shader")
{}

但是我可以看到你的Shader是虚拟类,你很可能真的想让着色器具有多态性。在这种情况下,您实际上需要存储作为指针,并且可能为Render构造函数提供实际的实现,如:

class Render
{

public: 
    Render(Shader *p_shader = NULL)
       : shader(p_shader)
    {}

    ~Render()
    { delete shader; }
protected:
private:
    Shader *shader;
};

要么禁用复制构造和赋值,要么提供它们并确保将着色器复制到那里以避免破坏时双重释放。

最好还是使用std :: unique_ptr甚至std :: shared_ptr(使用shared_ptr可以使用编译器生成的副本和赋值)。

在声明Java背景时,请记住Java引用的等价物是C ++中的指针,即Java代码:

Shader shader = new Shader();

将C ++翻译为:

Shader *shader = new Shader();

(并且没有可用的垃圾收集,这就是使用智能指针的原因)。