-3

I have a solid understanding of Java, but i'm trying to learn c++ to make a game and because I think c++ is a better language. But i'm having some problems with c++.

#ifndef RENDER_H
#define RENDER_H

#include "shader.h"
class Render
{

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

#endif

Shader is a class with a string constructor, just declaring it in this class causes an error. If I remove the constructor for Shader I don't get the error.

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();
IInspectable
  • 46,945
  • 8
  • 85
  • 181

4 Answers4

3

shader is a class member of Render. When instantiating a Render object, the Shader object needs to be constructed along the way. Since it doesn't provide a default c'tor, it cannot be constructed (that's what the error message is telling you).

To work around this, either provide a default c'tor for Shader1), or use an initializer list for Renders c'tor:

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

or

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


1) Note: The compiler generates a default c'tor in case there aren't any c'tors defined. That's why removing Shaders custom c'tor appears to solve the issue.
IInspectable
  • 46,945
  • 8
  • 85
  • 181
1

Your problem lies within the Render constructer (not shown in your question). Because your class Render has a member variable Shader which only has a single constructor (taking a std::string parameter), you must explicitly call that constructor in your constructor initializer list:

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

If I remove the constructor for Shader I don't get the error.

Note that when you remove you Shader constructor, the compiler then generates a default constructor for you, which means you don't need to explicitly call the constructor in Render (although you should).

Community
  • 1
  • 1
Tas
  • 7,023
  • 3
  • 36
  • 51
0

This your description

Shader is a class with a string constructor, just declaring it in this class causes an error. If I remove the constructor for Shader I don't get the error

describes the problem. If you do not explicitly call the constructor of class Shader in the mem-initializer list of the constructor Render then the compiler tries to call the default constructor for data member Shader shader; . However it is not declared and the compiler issues an error.

Either call the constructor of class Shader in the mem-initializer list of the constructor Render specifying an argument or define the default constructor of the class Shader.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

Most likely you didn't provide the string to Shader constructor in the Render constructor. You Render constructor needs to do something like this:

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

But as I can see that your Shader is virtual class, you most likely actually want to have the shader polymorphic. In such case you actually need to store is as a pointer and perhaps provide the actual implementation to the Render constructor, something like:

class Render
{

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

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

And either disable copy construction and assignment or provide them as well and ensure copying the shader there to avoid double free on destruction.

Better yet to use std::unique_ptr or even std::shared_ptr (with shared_ptr you can use the compiler generated copy and assignment).

As you declare Java background, remember the equivalent of Java reference is the pointer in C++, i.e. the Java code:

Shader shader = new Shader();

translates in C++ to:

Shader *shader = new Shader();

(and no garbage collection is available, that's why to use smart pointers).

EmDroid
  • 5,918
  • 18
  • 18