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

1

26.07.2013, 12:01

[C++] error C2582

Ich hab eine so definierte 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
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
#ifndef UNIT_DATA
#define UNIT_DATA

#include <SFML\Graphics.hpp>
#include <string>
#include <vector>

class c_framework;

class c_unit
{
    private:

        // references

        c_framework &framework;


        // unit data

        std::string name;

        sf::Sprite sprite;

        int hp_max;
        int hp_act;

        int atk_max;
        int atk_act;

        int def_max;
        int def_act;

        int run_max;
        int run_act;
        
    public:
        
        c_unit(c_framework &framework);


        // functions out

        void load_unit( std::string name_data );
        void set_sprite_pos( float x , float y );
        void draw();
        void update();
        void clear();

        int get_move();

};

#endif


Da es Einheiten für Spieler und Gegner gibt, wollte ich diese in einem Vector ablegen in dieser 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
29
30
31
32
33
34
#ifndef UNIT_MANAGMENT
#define UNIT_MANAGMENT

#include <SFML\Graphics.hpp>
#include <string>
#include <vector>

#include "unit.hpp"

class c_framework;
class c_battle_background;

class c_unit_managment
{
    private:

        // references

        c_framework &framework;
        c_battle_background &background;

        // units

        std::vector< std::vector< c_unit > > test_1;
        std::vector< c_unit > test_2;
        
    public:

        c_unit_managment( c_framework &framework , c_battle_background &backgroundm );

        load_units();
};

#endif


In der Funktion "load_units()" wollte ich dann den Vector füllen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "unit_managment.hpp"

#include "battle_background.hpp"

c_unit_managment::c_unit_managment( c_framework &framework , c_battle_background &backgroundm ) : framework ( framework ) , background ( backgroundm )
{

}

void c_unit_managment::load_units()
{   
    std::vector< c_unit > temp_unit;

    c_unit temp( framework );

    test_1.push_back( temp_unit );  // das hier Ergibt den Fehler

    test_2.push_back( temp ); // das hier Funktioniert;
}


Dort bekomme ich aber leider den Fehler wenn ich wie beim Beispiel "test_1" vorgehen will. Über Google habe ich schon herausgefunden, dass meine Klasse anscheinend nicht Kopierbar ist, vermutlich wegen der Referenz in ihr. Aber dann dürfte ich doch in test_2 das "temp" Object auch nicht reinschieben können oder?

Die Referenz in der "c_unit" Klasse könnte ich rausnehmen, wenn ich das sf::Sprite einfach in der "c_unit_managment" Klasse noch mitverwalte. Aber gäbe es auch noch andere Lösungen? Aus den Englischen Texten die ich über Google gefunden habe, bin ich leider nicht ganz schlau geworden, was es da alles für Lösungen gäb die ich Anwenden könnte.

Ich könnte natürlich auch einfach mehrere "test_2" vectoren verwenden, aber diese Lösung gefällt mir nicht wirklich. Dann muss ich mit mehreren ifs immer abfragen, auf welchen ich jetzt zugreifen will.

Zum Abschluss noch der Fehlermeldungstext:

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
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2514): error C2582: Die Funktion 'operator =' ist in 'c_unit' nicht verfügbar
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2535): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_OutIt std::_Move<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_Nonscalar_ptr_iterator_tag)".
1>          with
1>          [
1>              _OutIt=c_unit *,
1>              _InIt=c_unit *
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector(1202): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_OutIt std::_Move<c_unit*,c_unit*>(_InIt,_InIt,_OutIt)".
1>          with
1>          [
1>              _OutIt=c_unit *,
1>              _InIt=c_unit *
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector(1190): Bei der Kompilierung der  Klassen-template der std::_Vector_iterator<_Myvec> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Myvec>,std::_Vector_const_iterator<_Myvec>)-Memberfunktion
1>          with
1>          [
1>              _Myvec=std::_Vector_val<c_unit,std::allocator<c_unit>>,
1>              _Ty=c_unit
1>          ]
1>          c:\users\shork\documents\visual studio 2010\projects\phönix\phönix\unit_managment.cpp(14): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "std::vector<_Ty>".
1>          with
1>          [
1>              _Ty=c_unit
1>          ]

2

26.07.2013, 12:53

"Die Funktion 'operator =' ist in 'c_unit' nicht verfügbar"
Einmal den =-Operator in c_unit definieren.

MfG
Check

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

3

26.07.2013, 13:24

Die frage ist ja, wieso der =operator implizit geöscht wurde. und das liegt anscheinend daran, dass sf::Sprite keinen copy-konstruktor hat.
Eine möglchkeit, die dir bleibt, ist den operator = zu überladen, und dann musst du eine kopier-operation für sf::sprite basteln.
In dem fall würde es wahrscheinlich aber mehr sinn machen, unit_c instanzen mit new zu erzeugen, anstatt sie auf dem stack/vector zu verwalten.
Dann würde dein vector halt nur pointer/shared_pointer speichern und du müsstest unit_c nicht mehr kopieren
( was ja auch sinn macht, denn Entities kopiert man nicht :) (ok man klont sie vlt 8) )

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

26.07.2013, 14:28

sf::Sprite besitzt einen Copy-Konstruktor.
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]

5

26.07.2013, 14:39

@Databyte

Also an sf::Sprite liegt es nicht, sobald ich "c_framework &framework" in der "c_unit" Klasse ausklammere, funktioniert alles wieder einwandfrei. Auch wenn das sf::Sprite dann noch drin ist.


@Checkmateing

Darüber habe ich anscheinend noch garkeine Kentnisse und Google liefert mir nur was zum Überladen von operatoren, was ich auch noch nie gemacht habe. Muss ich da per Define den operator definieren oder nur für das Framework Referenz?

Hab mal probiert das hier einzufügen, was ich irgendwo gefunden hab:

C-/C++-Quelltext

1
c_framework& operator=( c_framework& framework );


Aber das liefert mir nur eine neue Meldung:

error C2679 : Binärer Operator '=' : Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'c_unit' akzeptiert (oder keine geeignete Konvertierung möglich )

Aber damit verlasse ich auch meinen Wissensbereich, also was ich damit jetzt genau gemacht hab und was mir die Meldung jetzt genau sagt, bin ich mir absolut unsicher.

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

6

26.07.2013, 16:41

Ups sprite hat natürlich einen impliziten copy-konstruktor ;)

Ok das Problem ist, dass du eine reference nicht zuweisen kannst. Du kannst sie zwar einmal initialisieren aber dann nicht mehr ändern.
Deshalb musst du aus der reference einen pointer machen! Anders geht es nicht, weil du die reference auch nicht zuweisen kannst,
wenn du einen =operator baust.

Oder wie oben schon gesagt: du erzeugst c_unit nur noch mit new und reichst dann nur noch pointer umher.

7

26.07.2013, 23:40

Benutze am besten gleich SmartPointer.
Eigentlich bezog ich mich auch eher auf c_unit, aber das wird in der Tat mit der Referenz eklig.
Ich nehme an, dass es nur ein Objekt c_framework geben darf. Mir wäre derartiges Rumgehampel zu nervig und ich würde das Objekt zumindest für die Bereiche, wo ich es garantiert benötige, global machen. Schau obs Sinn macht, so wie du es vorhast.

MfG
Check

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

8

27.07.2013, 01:59

Benutze am besten gleich SmartPointer.

Smartpointer in der Situation?
Framework wird wahrscheinlich nicht gelöscht bevor das Spiel beendet wird und die Unit besitzt es auch nicht, soll es also auch nicht löschen. Daher ist ein einfacher Zeiger hier eher angebracht. Wenn man mal davon absieht, dass es sowieso eine schlechte Idee ist. Aber dann eine noch schlechtere Idee vorschlagen... Lass das mit den globalen Variablen lieber!
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

9

27.07.2013, 12:02

Ich hab die Framework Referenz da jetzt einfach mal rausgeworfen und hab das Sprite ins Unit_Managment geschoben. Solange es bei einem einfachen Sprite bleibt, wird es dort jetzt auch drin bleiben, sollte ich aber Animationen noch vorsehen, werd ich wohl früher oder später vor dem gleichen Problem wieder stehen, nur mit einer anderen Klasse dann.

Was ich an dem aber jetzt noch nicht verstehe, warum bekomme ich den Fehler wenn ich einen leeren Vector in einen anderen Vector schieben will? Das Object als einzelnes kann ich ja wieder in einen Vector schieben ohne das ich Probleme bekomme. Aber warum ausgerechnet bei dem doppelten Vector?

Ja das Framework wird erst bei verlassen des Programms gelöscht, dass wird einmal in der "main.cpp" deklariert.


Die vernünftigste Lösung wäre also, sollte ich die Referenz drin behalten mögen, die c_units per new auf den Heap zu erzeugen oder? Ich frag deswegen noch, weil ich mir mit dem Aufbau des Programms noch nicht sicher bin, weil ich noch garnicht weiß was ich alles drin haben will. Also könnte es durchaus sein das ich später wieder einen Zugriff auf das Framework in der c_unit bräuchte. Oder der Fall im ersten Absatz trifft zu.

SmartPointer hätte ich garnicht, die gibts ja in VisualStudio 2010 noch nicht und boost habe ich bis jetzt noch nie benützt. :D

10

27.07.2013, 13:35

SmartPointer hätte ich garnicht, die gibts ja in VisualStudio 2010 noch nicht und boost habe ich bis jetzt noch nie benützt. :D

Ich hab zwar grad kein VC10 da, aber shared_ptr und unique_ptr sollten bereits vorhanden sein.
"Theory is when you know something, but it doesn’t work. Practice is when something works, but you don’t know why. Programmers combine theory and practice: Nothing works and they don’t know why." - Anon

Werbeanzeige