SFML community forums

Help => Graphics => Topic started by: Ignoscite Mihi on May 28, 2015, 04:48:02 pm

Title: Error with simple code
Post by: Ignoscite Mihi on May 28, 2015, 04:48:02 pm
Hi all. My problem is that I can't draw classes. Can anyone help me?



#include <SFML\Graphics.hpp>
using namespace sf;
class Rysunek : public Drawable
{
public:
private:
        virtual void draw(RenderTarget &target, RenderStates states) const;
};

int main()
{
        RenderWindow window(VideoMode(512, 512, 32), " aaa " , Style::Close);
        bool b = 1;
        Rysunek rys;
        while (b = 1)
        {
                Event a;
                while (window.pollEvent(a))
                {
                        if (a.key.code == Keyboard::Escape){
                                b = 0;
                                window.close();
                        }
                }

                window.clear(Color::Blue);
                window.draw(rys);
                window.display();
        }
        return 0;
}



1>------ Build started: Project: TEST, Configuration: Debug Win32 ------
1>  Source.cpp
1>Source.obj : error LNK2001: unresolved external symbol "private: virtual void __thiscall Rysunek::draw(class sf::RenderTarget &,class sf::RenderStates)const " (?draw@Rysunek@@EBEXAAVRenderTarget@sf@@VRenderStates@3@@Z)
1>C:\Users\user\Documents\Visual Studio 2013\Projects\TEST\Debug\TEST.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

And second code:

#include <SFML\Graphics.hpp>
using namespace sf;
class Rysunek : public Drawable
{
public:
        Texture texture;
        Sprite sprite(texture);
private:
        virtual void draw(RenderTarget &target, RenderStates states) const
        {
                target.draw(sprite);
        }
};

int main()
{
        RenderWindow window(VideoMode(512, 512, 32), " aaa ", Style::Close);
        bool b = 1;
        Rysunek rys;
        rys.texture.loadFromFile("a.png");
        while (b = 1)
        {
                Event a;
                while (window.pollEvent(a))
                {
                        if (a.key.code == Keyboard::Escape){
                                b = 0;
                                window.close();
                        }
                }

                window.clear(Color::Blue);
                window.draw(rys);
                window.display();
        }
        return 0;
}
{
        RenderWindow window(VideoMode(512, 512, 32), " aaa " , Style::Close);
        bool b = 1;
        Rysunek rys;
        while (b = 1)
        {
                Event a;
                while (window.pollEvent(a))
                {
                        if (a.key.code == Keyboard::Escape){
                                b = 0;
                                window.close();
                        }
                }

                window.clear(Color::Blue);
                window.draw(rys);
                window.display();
        }
        return 0;
}

1>------ Build started: Project: TEST, Configuration: Debug Win32 ------
1>  Source.cpp
1>c:\users\user\documents\visual studio 2013\projects\test\test\source.cpp(7): error C2061: syntax error : identifier 'texture'
1>c:\users\user\documents\visual studio 2013\projects\test\test\source.cpp(11): error C3867: 'Rysunek::sprite': function call missing argument list; use '&Rysunek::sprite' to create a pointer to member
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Title: Re: Error with simple code
Post by: shadowmouse on May 28, 2015, 04:50:38 pm
Try making draw() protected not private.
Title: Re: Error with simple code
Post by: Ignoscite Mihi on May 28, 2015, 05:01:15 pm
Try making draw() protected not private.

Still not working.

1>------ Build started: Project: TEST, Configuration: Debug Win32 ------
1>  Source.cpp
1>Source.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall Rysunek::draw(class sf::RenderTarget &,class sf::RenderStates)const " (?draw@Rysunek@@MBEXAAVRenderTarget@sf@@VRenderStates@3@@Z)
1>C:\Users\user\Documents\Visual Studio 2013\Projects\TEST\Debug\TEST.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Title: Re: Error with simple code
Post by: shadowmouse on May 28, 2015, 05:04:03 pm
Okay, does it work if you get rid of virtual? Also, you should be using
Code: [Select]
while(b) not
Code: [Select]
while(b=1)
Title: Re: Error with simple code
Post by: eXpl0it3r on May 28, 2015, 05:05:31 pm
No removing virtual doesn't change a thing.

The draw method needs to be public in the final drawable.
Title: Re: Error with simple code
Post by: Ignoscite Mihi on May 28, 2015, 05:08:06 pm
Okay, does it work if you get rid of virtual? Also, you should be using
Code: [Select]
while(b) not
Code: [Select]
while(b=1)

1>------ Build started: Project: TEST, Configuration: Debug Win32 ------
1>  Source.cpp
1>Source.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall Rysunek::draw(class sf::RenderTarget &,class sf::RenderStates)const " (?draw@Rysunek@@MBEXAAVRenderTarget@sf@@VRenderStates@3@@Z)
1>C:\Users\user\Documents\Visual Studio 2013\Projects\TEST\Debug\TEST.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Title: Re: Error with simple code
Post by: G. on May 28, 2015, 05:09:17 pm
#include <SFML\Graphics.hpp>
using namespace sf;
class Rysunek : public Drawable
{
public:
        Texture texture;
        Sprite sprite(texture);
That's not how you initialize a class member variable.
Title: Re: Error with simple code
Post by: eXpl0it3r on May 28, 2015, 05:10:05 pm
That's not how you initialize a class member variable.
It works in C++11, called "member initializers" (https://en.wikipedia.org/wiki/C++14#Aggregate_member_initialization). ;)
Title: Re: Error with simple code
Post by: victorlevasseur on May 28, 2015, 05:37:25 pm
The draw method needs to be public in the final drawable.
Title: Re: Error with simple code
Post by: Ignoscite Mihi on May 28, 2015, 06:18:39 pm
It's not working.
Title: Re: Error with simple code
Post by: shadowmouse on May 28, 2015, 06:20:32 pm
The draw method needs to be public in the final drawable.
Isn't RenderTarget a friend of Drawable so surely protected would work as well as public?
Title: Re: Error with simple code
Post by: eXpl0it3r on May 28, 2015, 06:39:39 pm
Isn't RenderTarget a friend of Drawable so surely protected would work as well as public?
Right, I forgot. :D

The fact that you posted two separate issues confused me a lot...

The linker error gets generated because you don't implement the draw function.
And the compiler error gets generated because as G. said that's not how you initialize member variables (I was wrong again).
Title: Re: Error with simple code
Post by: Nexus on May 28, 2015, 06:47:21 pm
Isn't RenderTarget a friend of Drawable so surely protected would work as well as public?
This has nothing to do with friend -- that keyword is not transitive, so the visibility of your derived classes' methods doesn't matter. Furthermore, the existence of a friend relationship is almost always an implementation detail, don't rely on it as a API user unless it's explicitly documented. Since it is mostly applied only between internal classes, there's no way you can benefit from it anyway.

By the way, it's perfectly valid to override virtual methods in the private section; reducing visibility just doesn't make too much sense generally, because the method can still be accessed via base class.
Title: Re: Error with simple code
Post by: Ignoscite Mihi on May 29, 2015, 05:29:10 pm
The linker error gets generated because you don't implement the draw function.
And the compiler error gets generated because as G. said that's not how you initialize member variables (I was wrong again).

I'm confused now. Anyway it don't work with initializing other class members than draw.
Title: Re: Error with simple code
Post by: Hapax on May 29, 2015, 08:06:52 pm
Ignoscite, the two lines from that quote refer to your different codes. The first line, your first code. The second line, your second code.

The first one fails because draw isn't implemented anywhere i.e. it's missing.

The second one fails because you should initialise a member variable in its constructor (body or "initialization list").
(In this case, it's because the texture that you're trying to create the sprite from hasn't been created yet - only declared).
I just noticed that your drawable class doesn't have a constructor. Time to make one  ;)

p.s. I don't know if you realised but your second code has the body of main() pasted twice.
Title: Re: Error with simple code
Post by: Ignoscite Mihi on May 30, 2015, 11:33:43 am
p.s. I don't know if you realised but your second code has the body of main() pasted twice.

Just little mistake while copying. Both codes were made fast. Okay now I see what I was making wrong. Thanks for help. :-)