Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

xXSlayerXx

Treue Seele

  • »xXSlayerXx« ist der Autor dieses Themas

Beiträge: 111

Beruf: Technischer Produktdesigner

  • Private Nachricht senden

1

22.05.2013, 23:26

[C++] OOP Variable aus klasse ändern.

Hi Leute,

nach langer Zeit melde ich mich auch mal wieder zu Wort ;)

Ich habe ein Problem.
Vorweg ein Codebeispiel:

C-/C++-Quelltext

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
class cTest1
{
public:
     void SetChecked(bool p1);

private:
     bool Checked;
}
void cTest1::SetChecked(bool p1)
{
     Checked = p1;
}

class cTest2
{
public:
     cTest1 GetKlasse1();

private:
     cTest1 Klasse1;
}
cTest1 cTest2::GetKlasse1()
{
     return Klasse1;
}

int main()
{
     cTest2 Klasse2;
     Klasse2.GetKlasse1().SetChecked(true);

     return (0);
}


Also zur erklärung.
Ich möchte den Wert aus der klasse cTest1 Klasse1 verändern.
Jedoch klappt das ganze nicht.
Der Wert bleibt einfach das, was er auch vorher war.

Weiß jemand woran das ganze liegt?
Ich hoffe mir kann da jemand weiterhelfen.

Ich hoffe der Code ist verständlich. Musste ihn vom Handy aus schreiben. ^^

Mit freudlichem Gruß
xXSlayerXx
Bestes Zitat aus einem Quellcode :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
/** 
Once you are done trying to ‘optimize’ this routine, 
and have realized what a terrible mistake that was, 
please increment the following counter as a warning 
to the next guy: 

total_hours_wasted_here = 11 
*/

Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

22.05.2013, 23:47

Die Funktion cTest2::GetKlasse1() gibt eine Kopie von Klasse1 zurück. Entsprechend wird die Kopie verändert und nicht das Objekt das du gerne ändern würdest. Schau dir mal das Thema Referenzen oder auch Zeiger an.

xXSlayerXx

Treue Seele

  • »xXSlayerXx« ist der Autor dieses Themas

Beiträge: 111

Beruf: Technischer Produktdesigner

  • Private Nachricht senden

3

23.05.2013, 00:02

sowas dacht ich mir schon, dass ich da nen zeiger übergeben muss.
Ich guck morgen mal, wie ich das hinbekomme.

Heute hat man mir zum ersten mal richtig erklärt, worauf es bei oop genau ankomt xD
Bestes Zitat aus einem Quellcode :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
/** 
Once you are done trying to ‘optimize’ this routine, 
and have realized what a terrible mistake that was, 
please increment the following counter as a warning 
to the next guy: 

total_hours_wasted_here = 11 
*/

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

23.05.2013, 06:44

Technisch gesehen solltest Du lieber eine Referenz zurückgeben. Praktisch gesehen solltest Du Dir überlegen wieso überhaupt jemand von außerhalb den Wert einer internen Instanz verändern dürfen soll und maximal eine const-Referenz zurückgeben. Das geht außen jedoch eigentlich niemanden was an und wenn doch, sollte cTest2 eine direkte Methode dafür anbieten und *keine* Get-Methode.

Ein paar Anmerkungen zum Stil:
1) Lass das "c" Präfix weg, das macht heute niemand mehr und ist überflüssig.
2) "Klasse1" ist genau genommen eine Instanz, daher ist "Klasse" da als Name semantisch falsch gewählt.
3) "Klasse1" sagt nichts über ihren Zweck. Der Name ist bedeutungslos. Sofern das nicht nur ein Beispiel war, ändere das lieber, sonst weißt Du in zwei Wochen selbst nicht mehr, wofür das Ding da ist.
4) Als guter Stil hat sich herausgestellt, dass man Klassennamen am Anfang groß schreibt und Variablen-Namen klein.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

xXSlayerXx

Treue Seele

  • »xXSlayerXx« ist der Autor dieses Themas

Beiträge: 111

Beruf: Technischer Produktdesigner

  • Private Nachricht senden

5

23.05.2013, 08:10

war alles nur ein beispiel^^
ich würde niemals eine Klassen instanz Klasse1 nennen.

Was genau meinst su mit direkter Methode?
Also dass ich Klasse1 public mache und dann auf sie zugreife?
Bestes Zitat aus einem Quellcode :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
/** 
Once you are done trying to ‘optimize’ this routine, 
and have realized what a terrible mistake that was, 
please increment the following counter as a warning 
to the next guy: 

total_hours_wasted_here = 11 
*/

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

23.05.2013, 08:35

Nein, ich meine eine Methode, die das nach außen kapselt.
Statt dass jemand foo.getKlasse1().setChecked(); aufrufen darf, würde ich nur foo.setChecked(); anbieten, was dann intern Klasse1.setChecked() aufruft. Damit sind die internen Details der Klasse nach außen versteckt. Die gehen nämlich niemanden etwas an.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

xXSlayerXx

Treue Seele

  • »xXSlayerXx« ist der Autor dieses Themas

Beiträge: 111

Beruf: Technischer Produktdesigner

  • Private Nachricht senden

7

23.05.2013, 10:24

Ist ein wenig schlecht hier, da es sich um eine Button klasse handelt.
Also ich erstelle einen Button aus 3 Bitmaps mit hilfe der WinApi.

Es kann ja vorkommen, dass ich villeicht bis zu 20 Buttons auf dem Bildschirm habe.
Es wäre ja ein pures durcheinander, wenn ich nun für jeden Button 5 Funtkionen habe, mit setCheck();.
Bestes Zitat aus einem Quellcode :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
/** 
Once you are done trying to ‘optimize’ this routine, 
and have realized what a terrible mistake that was, 
please increment the following counter as a warning 
to the next guy: 

total_hours_wasted_here = 11 
*/

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

8

23.05.2013, 12:04

Dabei geht es jetzt um eine Programmdesign Frage. Bei einer GUI würde ich mir vorher aber vielleicht angucken wie andere das lösen. Vor allem wenn du grad erst mit OOP angefangen hast. Wenn du dein Button Beispiel noch mal in einer richtigen Version zeigst, können wir dir ja Ratschläge für das Design geben.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

xXSlayerXx

Treue Seele

  • »xXSlayerXx« ist der Autor dieses Themas

Beiträge: 111

Beruf: Technischer Produktdesigner

  • Private Nachricht senden

9

23.05.2013, 13:50

Aber seit nicht zu streng, was die Programmierung angeht.

Hier mal meine Button klasse:

C-/C++-Quelltext

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
class BitmapButton
{
public:
    HWND CreateButton(HWND hWnd, HINSTANCE hInstance, int id, int x_pos, int y_pos,LPCSTR up, LPCSTR hover, LPCSTR down);
    void PaintButton();
    int GetButtonState();

    //Konstruktor
    BitmapButton();
    //Destruktor
    ~BitmapButton();
        
private:        
    void SetButtonBitmapPressed();
    void SetButtonBitmapHighlight();
    void SetButtonBitmapNormal();

    bool CheckMouseOver();

    HBITMAP ButtonNormal;
    HBITMAP ButtonPressed;
    HBITMAP ButtonMouseOver;
    HWND hWnd;
    bool pressed;

    //BitmapStates 0=Up, 1=Hover, 2=Down
    int BitmapState;
};


und hier die dazugehörenden Funktionen:

C-/C++-Quelltext

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "Buttons.h"

BitmapButton::BitmapButton()
{
    BitmapState=5;
}

BitmapButton::~BitmapButton()
{
    DestroyWindow(hWnd);
    DeleteObject(ButtonNormal);
    DeleteObject(ButtonPressed);
    DeleteObject(ButtonMouseOver);
    DeleteObject(hWnd);
}

bool BitmapButton::CheckMouseOver()
{
    POINT MausPos; 
    RECT Rect;

    GetWindowRect(hWnd,&Rect);
    GetCursorPos(&MausPos);
    if(hWnd != NULL)    
    {
        if(MausPos.x >Rect.left && MausPos.x < Rect.right && MausPos.y < Rect.bottom && MausPos.y > Rect.top)   return true;
        else    return false;
    }
    else    return false;
}

void BitmapButton::SetButtonBitmapPressed()
{
    SendMessage(hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)ButtonPressed);
}

void BitmapButton::SetButtonBitmapHighlight()
{
    SendMessage(hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)ButtonMouseOver);
}

void BitmapButton::SetButtonBitmapNormal()
{
    SendMessage(hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)ButtonNormal);
}

HWND BitmapButton::CreateButton(HWND hWindow, HINSTANCE hInstance, int id, int x_pos, int y_pos,LPCSTR up, LPCSTR hover, LPCSTR down)
{
    this->ButtonNormal = LoadBitmap(GetModuleHandle(NULL), up);
    this->ButtonPressed = LoadBitmap(GetModuleHandle(NULL), down);
    this->ButtonMouseOver = LoadBitmap(GetModuleHandle(NULL), hover);

    this->hWnd = CreateWindow   ("STATIC",NULL,
                                WS_VISIBLE | WS_CHILD | SS_BITMAP,
                                x_pos, y_pos, 1, 1,
                                hWindow, (HMENU)id, hInstance, NULL);

    this->SetButtonBitmapNormal();
    return hWindow;
}

void BitmapButton::PaintButton()
{
    if(CheckMouseOver())
    {   
        if(GetAsyncKeyState (VK_LBUTTON) & 0x8000)
        {
            if(BitmapState != 2)
            {
                SetButtonBitmapPressed();
            }
            BitmapState = 2;
        }
        else if(BitmapState == 2)
        {
                SetButtonBitmapHighlight();
                BitmapState = 1;
        }
        else
        {
            if(BitmapState != 1)
            {
                SetButtonBitmapHighlight();
                BitmapState = 1;
            }
        }
    }
    else
    {   
        if(BitmapState != 0)
        {
            SetButtonBitmapNormal();
            BitmapState = 0;
        }
    }
}

int BitmapButton::GetButtonState()
{
    if(CheckMouseOver())
    {   
        if(GetAsyncKeyState (VK_LBUTTON) & 0x8000)
        {
            pressed = true;
            return (0);
        }
        else if(pressed == true)
        {
            pressed = false;
            return (1);
        }
        else
        {
            return (2);
        }
    }
    else return (0);
}


Ich habe es nun geschafft, dass mir die Funktionen nen Zeiger auf die Klasse gibt und ich diese so nutzen kann :)
Ist hauptsächlich bei der Funktion CreateButton notwendig.
Bestes Zitat aus einem Quellcode :D

C-/C++-Quelltext

1
2
3
4
5
6
7
8
/** 
Once you are done trying to ‘optimize’ this routine, 
and have realized what a terrible mistake that was, 
please increment the following counter as a warning 
to the next guy: 

total_hours_wasted_here = 11 
*/

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

23.05.2013, 14:14

Es gibt natürlich beliebig viele Möglichkeiten, wie du sowas realisieren kannst. So ein GUI Design kann auch beliebig komplex, bzw aufwendig zu erstellen sein. Eigentlich möchte man ja möglichst in seinem Anwendungscode wenig Zeug für die GUI haben. Die GUI soll gerendert werden und man möchte irgendwie über einen Klick auf einen Button informiert werden. Je nachdem was du noch für Elemente bei deiner GUI benutzt gibt es dann halt andere Informationen die du erhälst, bzw an die GUI gibst. Das heißt, Funktionen zum setzen eines Buttonzustandes möchtest du eigentlich nicht unbedingt in deinem Anwendungscode haben. Was du machen kannst ist dir eine DLL zu schreiben, in welche du deinen GUI Code auslagerst. Funktionen zum setzen von Zuständen etc werden als internal deklariert, sodass du nur innerhalb der DLL darauf zugreifen kannst. Hier handelst du jetzt den ganzen Code ab, der die GUI Logik steuert. Es soll also möglichst automatisch erkannt werden, wenn ein Button geklickt wird und allgemeine Zustandsänderungen sollten auch hier abgehandelt werden. In der eigentlichen Anwendung solltest du möglichst nicht mehr tun müssen als den Button zu erstellen und zu benutzen. Wenn du dir mal andere GUI Frameworks anguckst, siehst du dass Zustandsänderungen oft durch Events umgesetzt werden. Wird zum Beispiel ein Button geklickt, so wird ein Event dafür gefeuert. So musst du in deinem Code nicht permanent den Zustand abfragen, sondern kannst einfach bei der Änderung darauf eingehen. Für die Implementierung von Events gibt es viele Möglichkeiten. Bei C++ ist es vermutlich das einfachste mit Funktionszeigern zu arbeiten. So gibst du der Instanz des Buttons eine Funktion an, welche er aufruft sobald ein bestimmter Zustand erreicht wird. Zum Beispiel eine Funktion die aufgerufen wird, sobald der Button geklickt wird. Wie gesagt, je weniger GUI Logik du in deiner eigentlichen Anwendung hast, umso übersichtlicher ist es für dich. Am besten guckst du dir andere GUIs an. Vielleicht einfach mal einen Blick in Windows Forms werfen. Einfach nur um zu sehen wie du da einen Button benutzt und was du selbst machen musst.
Ist natürlich nur ein Vorschlag ans Design. Wie bereits gesagt gibt es viele Möglichkeiten sowas umzusetzen. Der hier ist noch relativ einfach und lässt viele Freiheiten. Wenn du mal ein paar GUI Systeme benutzt siehst du aber recht schnell was du unbedingt haben möchtest, was du gern haben möchtest, was du unter Umständen haben möchtest und was du gar nicht haben möchtest.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige