Polymorphism

Sep 29, 2010 at 9:22pm
Hello there. I know this website has a great tutorial on Polymorphism, but I seem to have run into a bit of a problem. Basically I'm making a GUI using SDL. That's not the important part though :D.

Okay, so whenever I make a dynamically allocated array, I use a "vessel" class, which contains an abstract class ("you can't have a dynamic-alloc array of an abstract class" says Visual C++ 2008 -_-). So I did that, and I have an entity class, which contains that dynamically allocated array, and I update it every time you add something like... a button. Now, whenever I call the abstract class's display function, the display does not work, the program using the DLL just whines about it not working. I was sure to make the Display functions External btw.

Any help would be appreciated, and if you'd like my source code to check something, just let me know, but the DLL compiled perfectly fine.
Sep 30, 2010 at 1:58am
Rather than an array of objects, try an array of pointers to objects, if you want the contained objects to do polymorphism.

(I am guessing here since I see no source code)
Last edited on Sep 30, 2010 at 2:01am
Sep 30, 2010 at 2:15am
Oh well, I guess I can show you the source then, if you need it.

This is the header containing all of the classes.

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
#ifndef GUI_H_
#define GUI_H_
#define DLL_Export __declspec(dllexport)
#include <SDL.h>
#include <string>

namespace GUI{
    class Segment{
    protected:
        SDL_Rect area; // Area (all segments)
        //std::string label; // Label (almost all segments)
        bool transparent; // W-o-N the segment should be displayed
    public:
        // Virtual destructor
        DLL_Export virtual ~Segment(void){};

        DLL_Export virtual void Display(SDL_Surface *surface){}; // Display segment
        DLL_Export int X(){return area.x;}; // Return x position
        DLL_Export int Y(){return area.y;}; // Return y position
        DLL_Export int W(){return area.w;}; // Return width
        DLL_Export int H(){return area.h;}; // Return height
        //DLL_Export std::string Label(){return label;}; // Return the label
    };
    class SegVessle{
    public:
        // Constructor and destructor
        SegVessle(void);
        ~SegVessle(void);

        Segment *segment; // Segment instance
    };
    class Button : public Segment{
    public:
        // Constructor and destructor
        DLL_Export Button(int x, int y, int w, int h, bool transparent);
        DLL_Export ~Button(void);

        DLL_Export void Display(SDL_Surface *buffer); // Inherited from Segment
    };
    class Entity{
    private:
        bool transparent; // Whether or not the entity should be displayed
        SegVessle* segment; // Dynamically Allocated Array of Segments used in the entity
        SDL_Rect area; // Area the entity takes up on screen
        int segCount; // Amount of segments the entity currently holds
        void IncSeg(); // Increases the dynamically allocated array size
    public:
        // Constructors and Destructors
        DLL_Export Entity(int x, int y, int w, int h, bool transparent);
        DLL_Export ~Entity(void);

        DLL_Export void Display(SDL_Surface *buffer); // Draw the entity and all of its segments to the screen
        DLL_Export void Create(Button *button); // Adds a button to the entity
    };
}

#endif // GUI_H_ 


and this is the Source file for the Entity class

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
62
63
64
65

#include "GUI.h"

GUI::Entity::Entity(int x, int y, int w, int h, bool transparent){
	area.x = x;
	area.y = y;
	area.w = w;
	area.h = h;

	this->transparent = transparent;

	segment = NULL;

	segCount = 1;
}

GUI::Entity::~Entity(void){
	delete [] segment;
	segment = NULL;
}

void GUI::Entity::Display(SDL_Surface *buffer){
	if (!transparent){
		SDL_FillRect(buffer, &area, 0xCC0000);
	}
	if (segment != NULL){
		for (int x = 0; x < segCount; x++){
			segment[x].segment->Display(buffer);
		}
	}
}

void GUI::Entity::Create(GUI::Button *button){
	if (segment == NULL){
		segment = new SegVessle[1];
		segment[segCount].segment = button;
		segCount++;
	} else {
		IncSeg();
		segment[segCount].segment = button;
	}
}

void GUI::Entity::IncSeg(){
	if (segment != NULL){
		SegVessle* tempArray = new SegVessle[segCount];

		for (int x = 0; x < segCount; x++){
			printf ("Drawing first segment.");
			tempArray[x] = segment[x];
		}
	
		delete [] segment;
		segment = NULL;
		segCount++;
		segment = new SegVessle[segCount];

		for (int x = 0; x < segCount - 1; x++){
			segment[x] = tempArray[x];
		}

		delete [] tempArray;
		tempArray = NULL;
	}
}


Sep 30, 2010 at 6:47am
You should write a short test program where you just instantiate a button, and then call Display().

If you use a debugger, you will probably step into the implementation Button::Display() which may be implemented incorrectly (I'm guessing) - in other words, your virtual method hierarchy should be ok.

If my guesses are incorrect, you need to post your short test program and let me know what you found when you stepped through the debugger.
Last edited on Sep 30, 2010 at 6:48am
Topic archived. No new replies allowed.