Help with Virtual function

Ok so Im writing a program with SFML that requires more than one window, creating another is as easy as making a virtual function like this:

virtual int Run (sf::RenderWindow &Screen) = 0;

However when I run my program it says:

||=== Build: Debug in SFML Multiple Windows (compiler: GNU GCC Compiler) ===|
C:\Users\thund_000\Desktop\SFML Multiple Windows\main.cpp||In function 'int main()':|
C:\Users\thund_000\Desktop\SFML Multiple Windows\main.cpp|19|error: cannot declare variable 'strct' to be of abstract type 'Strct'|
C:\Users\thund_000\Desktop\SFML Multiple Windows\struct.h|4|note: because the following virtual functions are pure within 'Strct':|
C:\Users\thund_000\Desktop\SFML Multiple Windows\struct.h|8|note: virtual int Strct::Run(sf::RenderWindow&)|
C:\Users\thund_000\Desktop\SFML Multiple Windows\main.cpp|21|error: too many arguments to function 'void MainGame()'|
C:\Users\thund_000\Desktop\SFML Multiple Windows\Prototypes.h|7|note: declared here|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


So I made a test program and here is the code:

Main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <SFML/Graphics.hpp>

#include "Prototypes.h"
#include "struct.h"

using namespace std;

Strct::Strct(sf::RenderWindow &WINDOW, sf::VideoMode &VIDEOMODE): window(WINDOW), videoMode(VIDEOMODE)
{

}

int main()
{
    sf::RenderWindow win;
    sf::VideoMode vMode;

    Strct strct(win, vMode);

    MainGame(strct);
}


Window2.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <SFML/Graphics.hpp>

#include "Prototypes.h"

using namespace std;

void win2(Strct &strct)
{
    sf::RenderWindow secondWindow(sf::VideoMode(800, 600), "Second Window");

    while(secondWindow.isOpen())
    {
        secondWindow.clear();
        sf::Event event2;
        while(secondWindow.pollEvent(event2))
        {
            switch(event2.type)
            {
                case sf::Event::Closed:
                {
                    secondWindow.close();
                }
            }
        }
        secondWindow.display();
    }
}


Prototypes.h

1
2
3
4
5
6
7
8
9
#ifndef PROTOYTYPES_H_INCLUDED
#define PROTOYTYPES_H_INCLUDED

#include "struct.h"

void win2(Strct &strct);
void MainGame();

#endif // PROTOYTYPES_H_INCLUDED 



struct.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef STRUCT_H_INCLUDED
#define STRUCT_H_INCLUDED

struct Strct
{
    Strct(sf::RenderWindow &WINDOW, sf::VideoMode &VIDEOMODE);

    virtual int Run (sf::RenderWindow &Screen) = 0;

    sf::RenderWindow &window;
    sf::VideoMode& videoMode;
};

#endif // STRUCT_H_INCLUDED 


window1.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <SFML/Graphics.hpp>

#include "Prototypes.h"

void MainGame()
{
        sf::RenderWindow mainWindow(sf::VideoMode(800, 600), "Main Window");

    while(mainWindow.isOpen())
    {
        mainWindow.clear();
        sf::Event event;
        while(mainWindow.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                {
                    mainWindow.close();
                }break;
            }
        }



        mainWindow.display();
    }
}
Last edited on
virtual int Run (sf::RenderWindow &Screen) = 0; this is a pure virtual function which makes the object abstract. So you would need a child class to override the method. Is there a reason it is abstract I don't really see a reasoning especially since it is a struct which are normally meant for POD types. Would you please explain what you are attempting to do with our "Strct" class? I am dumbfounded.

* http://www.cplusplus.com/doc/tutorial/polymorphism/ Check out the bottom half of this page
Last edited on
I'm just trying to follow this tutorial, I copied the entire code and i get tons of errors:

https://github.com/LaurentGomila/SFML/wiki/Tutorial:-Manage-different-Screens

I want to make windows without having to do this but if this is the only way i guess i'll have to do it.
Last edited on
Ok well I just got done reading his tutorial and looking through your reference link and i'll just have to put off other windows for now, I dont know how to use virtual so i'll have to practice, I cant expect t just cobble together some classes and expect it to work, so i'll just wait.
See the thing is they make their classes children of the abstract class and override the virtual method. Here is what they do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

struct cScreen
{
    virtual int Run(sf::RenderWindow &App) = 0;
};


class Screen_1 : public cScreen
{
    public:
        virtual int Run(sf::RenderWindow &App)
        {
             //override function
        }
};

class Screen_2 : public cScreen
{
    public:
        virtual int Run(sf::RenderWindow &App)
        {
             //override function
        }
};


That way when you call the Run method it actually knows what to do.

I suggest you lok at their tutorial again.
Last edited on
Ok so I used to know what virtual did, its been such a long time since i used it, but basically it allows you to use multiple instances of 1 object right? so if i have an old man character sprite and i place 5 instances of him in my level and then i change the stats for each of them, then it will act as if each old man is different from the rest. Correct?
@Ch1156:

No, that is not correct.

Each object is already independent of all others. You do not need 'virtual' for that.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct Enemy
{
    int hp;
    int mp;
    int etc;
};

int main()
{
    // I can have as many 'Enemy's as I want.  Each one will have their own stats
   Enemy bob;
   Enemy joe;

   bob.hp = 100;
   joe.hp = 50;
   // etc.
}


What virtual does is allow a class to behave polymorphicly.

Polymorphism let's you have multiple classes that behave differently, but have them all share a common interface. If you give them all a common parent class... you can use that parent class to interface with any of the child classes.
Well what im building is an editor, where character sprites are loaded into it and the user can click and place them in the world. So the characters will all be loaded from one spot int he code, from one variable and then pushed back into a vector, so if i want to place for example an old man character, and then place 5 more in the level and then change his attributes, like change his health and what he says, i dont want his stats to override the other old men, so what do i do there? I'm not going to hard code character sprite names into the engine because i dont know how many the developer will want or what their names will be so doing the vector idea is the only solution i can think of.
Last edited on
from one variable and then pushed back into a vector,


Once you push_back something into a vector, then a copy of it is put in the vector. So each element in the vector will be its own unique object (assuming you have a vector of objects and not a vector of pointers)

so if i want to place for example an old man character, and then place 5 more in the level and then change his attributes, like change his health and what he says, i dont want his stats to override the other old men, so what do i do there?


You don't have to do anything special. That is what will be done by default. Each element in the vector is its own object... and each object has its own copy of all stats. Changing one will not affect any others.
Ok so i'm thinking polymorphism would be best for this task. so I would do something like this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>

using namespace std;

class NPC
{
    protected:
        int health;
        string name;

    public:
        void SetName(string NPCNAME)
        {name = NPCNAME;}

        void SetHealth(int HEALTH)
        {int health = HEALTH;}
};

class Farmer : public NPC
{
    public:
        string GetName()
        {return name;}

        int GetHealth()
        {return health;}
};

class Knight : public NPC
{
    public:
        string GetName()
        {return name;}

        int GetHealth()
        {return health;}
};

int main()
{
    Farmer farmer;
    Knight knight;
    NPC * npc1 = &farmer;
    NPC * npc2 = &knight;
    npc1->SetHealth(60);
    npc1->SetName("Farmer 1");

    npc2->SetHealth(700);
    npc2->SetName("Knight Boss");

    cout << "Farmer Stats\n" << endl;

    cout << farmer.GetHealth() << endl;
    cout << farmer.GetName() << endl;

    cout << "Knight Stats\n" << endl;
    cout << knight.GetHealth() << endl;
    cout << knight.GetName() << endl;

    return 0;
}


The health values come out weird numbers for some reason though.
I think using components would be better IMHO. Whats the difference between a farmer and a knight? Well a farmer has health while a knight has health and a weapon.

Also with your example you might as well just do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class NPC
{
    protected:
        int health;
        string name;

    public:
        void SetName(string NPCNAME)
        {name = NPCNAME;}

        void SetHealth(int HEALTH)
        {int health = HEALTH;}

        string GetName()
        {return name;}

        int GetHealth()
        {return health;}
};


...


NPC farmer;
NPC knight;

farmer.SetHealth(60);
farmer.SetName("Farmer 1");

knight.SetHealth(700);
knight.SetName("Knight Boss");
Though in this case I would use a map anyways.

Well I would rather just stick to this right now. Also so in your code that would be better. the user will be able to upload different characters and upload as many as they want so having a class with a specific name wont work for me but i was just using that as an example.
Topic archived. No new replies allowed.