Vaios Argiropoulos
Vaios Argiropoulos

Reputation: 387

Small sample program gives me an error

My sample program is so small that i am going to give you all the source code below:

So here is ClassA header:

#ifndef CLASSA_H
#define CLASSA_H
#include <string>

class ClassA
{
public:
    ClassA(const std::string& fileName,  int TYPE = 0, float filter = 0.0f);
    ClassA(int width = 0, int height = 0, unsigned char* data = 0, int TYPE = 0, float   filter = 0.0f);
    ClassA(ClassA& classa);
    void operator=(ClassA& classa);
protected:

private:
    std::string m_lastBind;
    int m_textureTarget;
    bool m_freeTexture;
    int m_width;
    int m_height;
    float m_float;

};

#endif // CLASSA_H

Here is the source file for the ClassA:

#include "classa.h"

ClassA::ClassA(const std::string& fileName, int TYPE, float filter)
{
    m_lastBind = fileName;
    m_textureTarget = TYPE;
    m_float = filter;
}


static unsigned char whitePixel[] = {'A', 'B', 'B', 'A'};

ClassA::ClassA(int width, int height, unsigned char* data, int TYPE, float filter)
{
    m_width = width;
    m_height = height;
    data = whitePixel;
    m_textureTarget = TYPE;
    m_float = filter;
}


ClassA::ClassA(ClassA& classa)
{
    m_width = classa.m_width;
    m_height = classa.m_height;
    m_textureTarget = classa.m_textureTarget;
    m_float = classa.m_float;
}

Here is the header file for ClassB:

#ifndef CLASSB_H
#define CLASSB_H
#include <string>

class ClassB
{
    public:
        void someMethod(const int& num1, const int& num2, std::string& name);
    protected:

    private:
};

#endif // CLASSB_H

And finally the definition of the one and only method of ClassB is given below:

#include "classb.h"
#include "classa.h"

static unsigned char whitePixel[] = {0xFF, 0xFF, 0xFF, 0xFF};
void ClassB::someMethod(const int& num1, const int& num2, std::string& name)
{
    static ClassA WHITE = ClassA(1,1,whitePixel);
}

The main function is pretty much irrelevant because it is completely empty and has nothing to do with the errors i am getting from Code::Blocks. The errors are given below:

||=== Build: Debug in Testing2 (compiler: GNU GCC Compiler) ===|
classb.cpp||In member function ‘void ClassB::someMethod(const int&, const int&, std::string&)’:|
classb.cpp|8|error: no matching function for call to ‘ClassA::ClassA(ClassA)’|
classb.cpp|8|note: candidates are:|
classa.h|10|note: ClassA::ClassA(ClassA&)|
classa.h|10|note:   no known conversion for argument 1 from ‘ClassA’ to ‘ClassA&’|
classa.h|9|note: ClassA::ClassA(int, int, unsigned char*, int, float)|
classa.h|9|note:   no known conversion for argument 1 from ‘ClassA’ to ‘int’|
classa.h|8|note: ClassA::ClassA(const string&, int, float)|
classa.h|8|note:   no known conversion for argument 1 from ‘ClassA’ to ‘const string& {aka const std::basic_string<char>&}’|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

Upvotes: 0

Views: 90

Answers (3)

Anton Savin
Anton Savin

Reputation: 41331

static ClassA WHITE = ClassA(1,1,whitePixel);

This is a copy-initialization, which semantically first creates the right part and then initializes the left part by calling copy constructor (this call may be elided but copy constructor still must be available). For direct initialization rewrite it as

static ClassA WHITE(1,1,whitePixel);

That said, copy constructor still should take a const reference or even be removed, as suggested by 0x499602D2.

Upvotes: 1

David G
David G

Reputation: 96845

This line:

static ClassA WHITE = ClassA(1,1,whitePixel);

needs a copy-constructor in order to work. The constructor ClassA(ClassA&) won't match because temporaries cannot bind to lvalue-references. You can make the constructor take a reference to const instead.

ClassA(ClassA const&);

This works because temporaries (rvalues) can bind to lvalue-references to const.


What were you were doing was creating a temporary ClassA value and copy-constructing WHITE from that. This is called copy-initialization. If you use direct-initialization instead:

static ClassA WHITE(1,1,whitePixel);

A copy-constructor simply copies all the members of the parameter to the object being created. Your code effectively does exactly the same thing. Fortunately the compiler will provide a copy-constructor for you by default, so you don't need to make one yourself.

Upvotes: 4

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385325

static ClassA WHITE = ClassA(1,1,whitePixel);

This constructs a temporary ClassA, then copy-constructs WHITE from it. The copy might be removed by optimisation but it must be possible.

You should simply directly declare WHITE:

static ClassA WHITE(1, 1, whitePixel);

Upvotes: 3

Related Questions