C++: how use arrays on our class's?

Pages: 12
see my 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
class Sprite
{
private:
    LPDIRECT3DDEVICE9 sprDevice=NULL;
    LPD3DXSPRITE sprSprite=NULL;
    LPDIRECT3DTEXTURE9 sprTexture=NULL;
public:
    int x=0;
    int y=0;
    int width=0;
    int height=0;

    Sprite(LPDIRECT3DDEVICE9 DXDev, string strFileImage)
    {
        sprDevice=DXDev;
        D3DXCreateSprite(sprDevice,&sprSprite);
        D3DXCreateTextureFromFile(sprDevice,strFileImage.c_str(),&sprTexture);
    }

    Sprite(LPDIRECT3DDEVICE9 DXDev, UINT ResourCeID)
    {
        sprDevice=DXDev;
        D3DXCreateSprite(sprDevice,&sprSprite);
        D3DXCreateTextureFromResource(sprDevice,GetModuleHandle(NULL),MAKEINTRESOURCE(ResourCeID),&sprTexture);
    }

    void Image(string strFileImage)
    {
        if( sprTexture != NULL )
            sprTexture->Release();
        D3DXCreateTextureFromFile(sprDevice,strFileImage.c_str(),&sprTexture);
    }

    void Image(UINT ResourCeID)
    {
        if( sprTexture != NULL )
            sprTexture->Release();
        D3DXCreateTextureFromResource(sprDevice,GetModuleHandle(NULL),MAKEINTRESOURCE(ResourCeID),&sprTexture);
    }

    void Draw(D3DCOLOR dxColor=D3DCOLOR_XRGB(255,255,255))
    {
        D3DXVECTOR3 vcPosition;
        vcPosition.x=x;
        vcPosition.y=y;
        vcPosition.z=0;
        sprSprite->Begin(D3DXSPRITE_ALPHABLEND);
        sprSprite->Draw(sprTexture,NULL,NULL,&vcPosition,dxColor);
        sprSprite->End();
    }

    ~Sprite()
    {
        if( sprSprite != NULL )
            sprSprite->Release();
        if( sprTexture != NULL )
            sprTexture->Release();
    }
};

heres how i use it on array:
1
2
3
4
5
Sprite sprDiamond[10];//10 elements of sprDiamond
for (int i=0; i<10; i++)
    {
        sprDiamond[i]=new Sprite(DX, Diamond);
    }

i get several errors about the assignment operator.
did i forget overload the assignment operator or i'm using the 'new' on wrong way?
Sprite sprDiamond[10];

That creates an array of ten Sprite objects. Not pointers to Sprite objects. Ten Sprite objects, all made using the default constructor. All made. Not an empty array. Not space for ten objects to go in when you make them. Ten Sprite objects, made.

So when you do this:

sprDiamond[i]=new Sprite(DX, Diamond);

on the left you have a Sprite object, already made, and on the right you have a pointer-to-a-Sprite. It makes no sense!
Last edited on
The new operator returns a pointer. But sprDiamond[i] is an object. Change your array to an array of pointers and you will be just fine.

works fine converting to a pointer.
but correct me more: all arrays, from my class, must be a pointer?
or i must do more on my class for fix it?
all arrays, from my class, must be a pointer?


No. If you make an array, you can make it an array of objects, or an array of pointers.
1st i add, now, an empty constructor:
1
2
3
4
Sprite()
    {
        //nothing;
    }

and now what i did:
1
2
3
4
5
6
7
Sprite sprDiamond[10];
for (int i=0; i<10; i++)
    {
        sprDiamond[i]= Sprite(DX, Diamond);
        sprDiamond[i].x=rand()%((SCREEN_WIDTH)-0 + 1) + 0;
        sprDiamond[i].y=rand()%((SCREEN_HEIGHT)-0 + 1) + 0;
    }

theres no compiler error.. only on execute mode: tell me that the program stops to responding and then it's automatic closed :(
so what i did wrong?
Your short code snippit looks OK from the surface... but clearly something is going wrong. When exactly does the program crash? Try going through it with a debugger, line by line.
Last edited on
i can show you:

https://imgur.com/a/hSCZ7

is what i have... nothing more
(it's on Portuguese: tell me that the program stops to responding and then it's automatic closed)
the constructor isn't called on 'for'(i'm testing)
Sorry, but that isn't what I'm asking. In order to solve your problem, you're going to need to know where in your code your program is crashing. You need to find which line, operation, or function in your code is causing the crash.

What are you building your program with? If you are working with an IDE such as Visual Studio, Code Blocks, Eclipse, or any other popular IDE, you will have the option of running your compiler in a Debug mode, where you "Step In" to your code, executing each line manually, one line at a time, to see when exactly an error happens.

If you don't have this or don't want to learn it, I would suggest otherwise, as it is a valuable skill. But nevertheless, if you can't use a debugger, then I would suggest putting print statements in the parts of the code where you are unsure what is happening.

Ex:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
void print(int n)
{
    std::cout << "Hello! #" << n << std::endl;
}
int main()
{
    print(1);
    int a = 3;

    a++;

    print(2);

    int* b = new int[10];
    b[123432] = 42;

    print(3);

    while (true) {}

    print(4);
}


1
2
3
possible output:
Hello! #1
Hello! #2 


We never see "Hello! #3", so we know the error is happening somewhere between print(2) and print(3). This narrows what is causing your program to crash.

Edit: I see your post above mine. Good to see you're testing it. Once you figure out where it's crashing, post the relevant set of functions or constructors, and say which line it's failing on.
Last edited on
i found that the problem was on Draw() member, that i did the change:
1
2
3
4
5
6
7
8
9
10
11
12
void Draw(D3DCOLOR dxColor=D3DCOLOR_XRGB(255,255,255))
    {
        if( sprSprite != NULL ||sprTexture != NULL )
            return;
        D3DXVECTOR3 vcPosition;
        vcPosition.x=x;
        vcPosition.y=y;
        vcPosition.z=0;
        sprSprite->Begin(D3DXSPRITE_ALPHABLEND);
        sprSprite->Draw(sprTexture,NULL,NULL,&vcPosition,dxColor);
        sprSprite->End();
    }

now, only when i close the apllication, i get the same error.
If you are getting an error only when you close the application, it could be because your program is trying to draw to a screen context that no longer exists.

I don't know how your main loop is set up, but try to see if that is what is happening.
the constructor give me the draw place and creates the sprite and texture.
i'm sorry, but lets go back...
if i use a pointer with the 'new' works fine. so why without a pointer and the 'new' isn't working?
Last edited on
Because they are two different types, so you have a type mismatch when you try to assign a Sprite pointer to a Sprite.

One is a Sprite. The other is a Sprite* (pointer to Sprite). The new operator returns a pointer to the newly-allocated heap memory. It doesn't return a Sprite object itself.

When you make an array of 10 Sprites,
Sprite sprDiamond[10];
you are making 10 objects on the stack, and sprDiamond[0] ... sprDiamond[9] are all Sprites that you can directly access.

https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
http://www.programmerinterview.com/index.php/data-structures/difference-between-stack-and-heap/
Last edited on
but works fine with a normal variable(not an array):
Sprite sprDiamond(DX, Diamond);
so i'm much more confused.
my C++ is limited and somethings aren't explained on books.
so how can i update my class for fix that?
I think by now you've made a number of changes to the code you initially posted. Why don't you post your latest code so we can see what you are working with now.

I have a comment on the following function posted a few comments back, but I don't know if it's the latest version or not any more.

1
2
3
4
5
6
7
8
9
10
11
12
void Draw(D3DCOLOR dxColor=D3DCOLOR_XRGB(255,255,255))
    {
        if( sprSprite != NULL ||sprTexture != NULL )
            return;
        D3DXVECTOR3 vcPosition;
        vcPosition.x=x;
        vcPosition.y=y;
        vcPosition.z=0;
        sprSprite->Begin(D3DXSPRITE_ALPHABLEND);
        sprSprite->Draw(sprTexture,NULL,NULL,&vcPosition,dxColor);
        sprSprite->End();
    }


In this function you return early if either sprSprite or sprTexture is NOT NULL. However, if both happen to be NULL, you will continue to perform the function. In this case, when you dereference sprSprite, you will have a segmentation violation because you are dereferencing a NULL pointer. Your check should instead be:

code]if( sprSprite == NULL || sprTexture == NULL )[/code]

In other words, only don't continue processing if either pointer is NULL.
yes... i have noticed that. and i fixed.
heres the entire 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
66
67
68
69
70
71
72
73
74
75
76
77
78
class Sprite
{
private:
    LPDIRECT3DDEVICE9 sprDevice=NULL;
    LPD3DXSPRITE sprSprite=NULL;
    LPDIRECT3DTEXTURE9 sprTexture=NULL;
public:
    int x=0;
    int y=0;
    int width=0;
    int height=0;
    bool visible=false;

    Sprite(LPDIRECT3DDEVICE9 DXDev, string strFileImage)
    {
        sprDevice=DXDev;
        D3DXIMAGE_INFO d3dIInfo;
        D3DXCreateSprite(sprDevice,&sprSprite);
        D3DXGetImageInfoFromFile(strFileImage.c_str(), &d3dIInfo);
        D3DXCreateTextureFromFile(sprDevice,strFileImage.c_str(),&sprTexture);
        width=d3dIInfo.Width;
        height=d3dIInfo.Height;
        visible=true;
    }

    Sprite(LPDIRECT3DDEVICE9 DXDev, UINT ResourCeID)
    {
        sprDevice=DXDev;
        D3DXIMAGE_INFO d3dIInfo;
        D3DXCreateSprite(sprDevice,&sprSprite);
        D3DXGetImageInfoFromResource(GetModuleHandle(NULL),MAKEINTRESOURCE(ResourCeID),&d3dIInfo);
        D3DXCreateTextureFromResource(sprDevice,GetModuleHandle(NULL),MAKEINTRESOURCE(ResourCeID),&sprTexture);
        width=d3dIInfo.Width;
        height=d3dIInfo.Height;
        visible=true;
    }

    void Image(LPDIRECT3DDEVICE9 DXDev, string strFileImage)
    {
        D3DXIMAGE_INFO d3dIInfo;
        sprDevice=DXDev;
        D3DXGetImageInfoFromFile(strFileImage.c_str(), &d3dIInfo);
        D3DXCreateTextureFromFile(sprDevice,strFileImage.c_str(),&sprTexture);
        width=d3dIInfo.Width;
        height=d3dIInfo.Height;
        visible=true;
    }

    void Image(LPDIRECT3DDEVICE9 DXDev, UINT ResourCeID)
    {
        D3DXIMAGE_INFO d3dIInfo;
        sprDevice=DXDev;
        D3DXGetImageInfoFromResource(GetModuleHandle(NULL),MAKEINTRESOURCE(ResourCeID),&d3dIInfo);
        D3DXCreateTextureFromResource(sprDevice,GetModuleHandle(NULL),MAKEINTRESOURCE(ResourCeID),&sprTexture);
        width=d3dIInfo.Width;
        height=d3dIInfo.Height;
        visible=true;
    }

    void Draw(D3DCOLOR dxColor=D3DCOLOR_XRGB(255,255,255))
    {
        D3DXVECTOR3 vcPosition;
        vcPosition.x=x;
        vcPosition.y=y;
        vcPosition.z=0;
        sprSprite->Begin(D3DXSPRITE_ALPHABLEND);
        sprSprite->Draw(sprTexture,NULL,NULL,&vcPosition,dxColor);
        sprSprite->End();
    }

    ~Sprite()
    {
        if( sprSprite != NULL )
            sprSprite->Release();
        if( sprTexture != NULL )
            sprTexture->Release();
    }
};

and i have fixed more 1 thing: the array must be initialized(i always write wrong).. i miss that:
Sprite sprDiamond[10]{{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond}};
now it's fixed. because the inicialization is when we create the array. if i need change it, i must use 'new' on 'for'.
yes my problem was really on array it self. but i never thinked on that.
thank you so much.
it's fixed, but i accept more information
This being C++, perhaps a vector is a better option than an array. Something like:
vector<Sprite> sprDiamond(10, Sprite (DX, Diamond));
to create a vector of ten Sprite objects, each one constructed with params (DX, Diamond) (or rather, one such object made and then copied repeatedly).


Well, I say "perhaps". Of course it is; vector over plain array, (almost) every time.
Last edited on
i did a big mistake without notice:
Sprite sprDiamond[10]{{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond},{DX, Diamond}};
like you see, i inicializate them on array. these is what i need... was better using the same data once hehehehe
thanks for all and Merry Christmas
Pages: 12