1

How can I declare an object without initializing it?

This is my header file

    #include "shader.h"

    Class Renderer {
        private:
        kaarez::graphics::Shader m_terrainShader;
    };

And my source file

    #include "Renderer.h"
    #include "Shader.h"

    Renderer::Renderer() {
        //Load terrain shader
        m_terrainShader =  kaarez::graphics::Shader("vertex.txt", "fragment.txt");
    }

I get the error that theres no appropriate default constructor available for Shader.

Shader is header-only, and it works when I declare it in the main method by kaarez::graphics::Shader terrainShader("vertex.txt", "fragment.txt");

What is wrong?

KaareZ
  • 615
  • 2
  • 10
  • 22
  • 1
    Your question is kinda unsolvable because C++ is **case-sensitive**. There is no `Class` keyword and `shader.h` is not `Shader.h`. – cadaniluk Nov 18 '15 at 16:41
  • Apparently my IDE/compiler is not case-sensitive for includes. Didn't change anything. – KaareZ Nov 18 '15 at 16:46

3 Answers3

3

Initialise the member variable in the constructors member initializer list like so:

Renderer::Renderer() : m_terrainShader("vertex.txt", "fragment.txt") {
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
2

You will need to initialize m_terrainShader in the class initializer list since it is not default constructable.

Renderer::Renderer() : m_terrainShader("vertex.txt", "fragment.txt"){}

The reason you have to do this is that when you enter the body of the constructor all of the class members are already initialized. Since m_terrainShader cannot be default initialized you have to explicitly initialize it.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Thank you, but is there no way that I can initialize Shader in the Renderer constructor? This solution is fine atm, but in the future I would like to initialize it in the constructor for several reasons. – KaareZ Nov 18 '15 at 16:44
  • Not if `Shader` is not default constructable. It is the preferred and sometimes only way to construct an object. http://stackoverflow.com/questions/926752/why-should-i-prefer-to-use-member-initialization-list – NathanOliver Nov 18 '15 at 16:48
  • Is the only solution the to re-initialize it? – KaareZ Nov 18 '15 at 16:55
  • @KaareZ Why would you need to re-initialize it? You can construct the members directly in the initialization list. can you show me an example of what you are trying to do and why list initialization does not work for you? – NathanOliver Nov 18 '15 at 16:58
  • I want to be able to choose which "vertex.txt" and "fragment.txt" to use. For example by loading a settings file in the Renderer constructor. Also I'm not a fan of the style, but that is of course second priority. – KaareZ Nov 18 '15 at 17:02
  • @KaareZ The only way is to use a pointer (`std::unique_ptr` ideally) for the `m_terrainShader` then. – πάντα ῥεῖ Nov 19 '15 at 08:53
  • @KaareZ It could also be possible to use a function to create the object that you want and call that function in the initializer list. `m_terrainShader(create_shader(some_values))` – NathanOliver Nov 19 '15 at 12:50
0

It's maybe not precisely an answer (and many years late), but in C++11 or greater, you can use a unique pointer (or a shared pointer).

in the header do:

unique_ptr<Treaderkaarez::graphics::Shader> m_terrainShader;

And in the code do

m_terrainShader.reset(new kaarez::graphics::Shader("vertex.txt", "fragment.txt"));

It's safer than a pointer because you don't have to worry about failure to delete it or deleting it without assigning it.