C++ chars in meiner Klasse lassen sich nicht mehr ändern!

C++11-LIKE

Cadet 1st Year
Registriert
Juli 2016
Beiträge
10
Hallo,

ich möchte zurzeit ein kleines Game in C++(Konsolenanwendung) programmieren und bin gerade am verzweifeln:freak:, weil ich eine Klasse für alle Level-Objeckte(alle als const char) geschrieben habe, diese sich jetzt aber nicht mehr ändern lassen! Z.B. schrieb ich zuerst in die Variable '#' - funktionierte prima - dann änderte ich diese in '*', jedoch zeigt mir die Konsole immernoch eine Raute an! Woher nimmt sie denn diese??? Liegt das evtl. an dem Objekt über das ich auf die Variable zugreife?

Ich hatte das problem schonmal, da habe ich die Variablen in den globalen Bereich verschoben - überhalb der main-Funktion - dann hat es geklappt, doch das ist doch auch keine Lösung!?

Ich würde mich sehr darüber freuen, wenn mir jemand helfen könnte! :)
 
Es ist bei sowas immer etwas schwierig zu helfen, wenn die Leute vergessen den etsprechenden Code zu posten. ;) Aber ich will es trotzdem mal versuchen:

So wie ich das verstehe gibst du erst ein Zeichen aus einer Variable auf der Konsole aus und änderst danach die entsprechende Variable, in der Erwartung, dass sich dann auch der Konsoleninhalt ändert. Die Konsole speichert aber eine Kopie der Zeichen und keinen Verweis auf deine Variable. Wenn du willst, dass sich der Inhalt ändert, musst du auch eine neue Ausgabe machen.
 
So ins Blaue geraten würde ich sagen: nimm mal das "const" weg.

Ansonsten brauchen wir, wie GeneralMelchett schon sagt, den Code. Sonst wird das hier nur ein rumgerate.
 
Das war auch mein erster Gedanke, das "const" steht halt für nicht änderbar.
Man darf einmal initialisieren, dann eben "konstant".
 
const klingt naheliegend als Grund aber kann es nicht sein, denn:
const ist eine compile-time überprüfung und hat zur Laufzeit keinen Effekt.
Daraus kann man schließen, dass der Fehler bei
Z.B. schrieb ich zuerst in die Variable '#' - funktionierte prima - dann änderte ich diese in '*', jedoch zeigt mir die Konsole immernoch eine Raute an!
liegen muss.
Dh der Variable wird nicht zur laufzeit der # und auch nicht später der * zugewiesen.
 
Zuletzt bearbeitet:
const-Fehler kann es nicht sein, weil bei erneuter Zuweisung ein Kompiler-Fehler entstanden wäre (Variable ist schließlich unveränderlich und es wird versucht sie zu verändern). Ich tippe darauf, dass du in deiner Char Klasse eine get-Funktion hast, die eine Kopie der entsprechenden Member-Variable zurückgibt und du dieser Kopie den neuen Wert zuweist, die eigentliche Member-Variable die ausgegeben wird daher unverändert bleibt. Aber ohne Code ist es wildes Gerate wie hier einige schon meinten ^^
 
Vielen Dank für die schnellen Antworten!
Ich habe jetzt das const weggenommen, um die Variablen mit settern ändern zu können( void set_zeichen(char zeichen){zeichen = zeichen} ). Im Hauptprogramm ändere ich jetzt die Variablen ganz am Anfang durch diese Methode/n.

Jetzt geht es! PRIMA! Vielen Dank!
Ergänzung ()

Ich arbeite mit der Entwicklungsumgebung Orwell Dev-C++. Als ich zuerst "Rebuild All" und dann "Compile and Run" drückte(sonst lasse ich immer "Rebuild All" weg), änderten sich die Zeichen endlich!

Danke für die schnelle Hilfe! :)
 
Wieso sind die Leute immer nur so geizig mit ihrem Code ? Meistens sind das diese Leute, die sich schämen anderen ihren Code zu zeigen.
 
Zuletzt bearbeitet:
Frage an den OP: Was hat dich dazu bewegt, das char-Member als const zu deklarieren, wenn du es doch aber eigentlich gar nicht konstant haben möchtest? Hast du den Sinn von const verstanden?
 
Diese Zeichen sollen in der Klasse einmalig erzeugt werden(für jedes Objekt bereitgestellt - deshalb nicht static) und im weiterem Programmverlauf nicht mehr geändert werden. Deshalb habe ich sie mit const definiert.
Ich wollte ihnen nur bei der Definition im Quellcode einen anderen Wert zuweisen, was zuerst nicht geklappt hat - die Konsole hat weiterhin das alte Zeichen ausgegeben, was eigentlich nirgens im Quellcode zu finden war.
 
Deshalb habe ich sie mit const definiert.
Das ist auch absolut richtig so und gehört sich auch so.
Dinge (member) die nur einmal einen Wert pro Instanz bekommen werden natürlich const gemacht - dafür ist es ja unter anderem da.
Hast du das auch richtig gemacht?
https://de.wikibooks.org/wiki/C++-Programmierung:_Klassen#Konstruktoren
Das mit dem Doppelpunkt vor der ersten { des Konstruktors meine ich.
Bei C++11 darfst du auch direkt in der Header schreiben
const int myMember = 10;
 
Den Konstruktor habe ich als Element-Initialisierer(oder wie man das auch immer nennt) geschrieben, ja, aber dieser belegt die Zeichen nicht mit einem Wert, weil die Zeichen nur von Methoden meiner Klasse genutzt werden - also nicht von erzeugten Objekten.
Bei C++11 darfst du auch direkt in der Header schreiben
const int myMember = 10;
--> genau so schreibe ich das.

Ich sende gleich mal den gesamten Quellcode ...
Ergänzung ()

Ich entschuldige mich für eventuellen geschriebenen Mist, jedoch ist das ganze ja noch "in der Entwicklung" und ich habe hier nur schnell meine Ideeen zusammengetragen und dann ein bisschen drüber nachgedacht - bis ich mir sagte: schreibe doch Klassen für deine Funktionen und Eigenschaften/Variablen, die vorher alle global definiert waren. Also machte ich das, und das brachte zuerst viele Fehlermeldungen mit sich(ich bin noch relativ beim Anfang mit C++ und betreibe ein Selbststudium mit einem tollen Buch und natürlich mit der Hilfe des Internets - An dieser Stelle möchte ich keine Werbung machen, aber wenn jemand einen guten Autor über IT-Dinge sucht, der ALLES wirklich ausführlichst und auch etwas locker bechreibt und erklärt, dann sucht nach Jürgen Wolf/Rheinwerk Verlag) ... aber jetzt der code:

HTML:
<hr />
game.cpp
HTML:
<hr />
Code:
#include "Data/lge.h"
#include "Data/lge/input.h"

int main() {
	Player *player = new Player;
	Input input;
	
	char new_door = 127;
	player->set_door(new_door);
	
	while ( true ) {
		input.set_keys(0, 0);
		input.waitForInput();
		input.make_keyXY();
		if ( input.get_end() ) return 0;
		
		player->set_ziel_x(player->get_x() + input.get_keyXY().first);
		player->set_ziel_y(player->get_y() + input.get_keyXY().second); 
		
		if (!(player->isALevelElement(
									 player->level.at(player->get_ziel_y()).at(player->get_ziel_x())
									))) 
		{
			player->set_x(player->get_ziel_x());
			player->set_y(player->get_ziel_y());
			player->refreshScreen();
			player->level.at(player->get_y()).at(player->get_x()) = player->get_playerICON();
			player->print();
		}
		else if ( player->level.at(player->get_ziel_y()).at(player->get_ziel_x()) == player->get_levelElement("door") ) {
			//player->showWinningText();
		}
		
	}
	delete player;
	return 0;
}

HTML:
<hr />
Data/lge.h
HTML:
<hr />
Code:
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
#include <utility>

#ifndef LGE_H
#define LGE_H

class Player {
private:
	char player;
	short x, y;
	short ziel_x, ziel_y;
	
	short leben;
	short munition;
	
public:          
	Player();
	Player(const char player_icon);
	Player(const char player_icon, short x, short y);
	
	void set_x(const short &xPos);
	void set_y(const short &yPos);
	short get_x() const;
	short get_y() const;
	void set_ziel_x(const short &xZielPos);
	void set_ziel_y(const short &yZielPos);
	short get_ziel_x() const;
	short get_ziel_y() const;
	const char get_playerICON() const;
	const char get_levelElement(std::string name) {
		if (name == "door") return door;
		else if (name == "wallSenkrecht") return wallSenkrecht;
		else if (name == "wallWaagerecht") return wallWaagerecht;
		else if (name == "border") return border;
		else if (name == "muniElement") return muniElement;
		else if (name == "leer") return leer;
		else {
			std::cerr << "FEHLER: \"" << name << "\" nicht bekannt!" << std::endl;
			// ...
		}
	}
	
	// Screen
		public:
			const short SIZE_X = 20;
			const short SIZE_Y = 10;
			void initScreen();
			void refreshScreen();
			void print();
			void showWinningText() {
				level.at(3).at(7) == 'Y';
				level.at(4).at(7) == 'o';
				level.at(5).at(7) == 'u';
				level.at(6).at(7) == '\'';
				level.at(7).at(7) == 'v';
				level.at(8).at(7) == 'e';
				level.at(9).at(7) == ' ';
				level.at(10).at(7) == 'w';
				level.at(11).at(7) == 'o';
				level.at(12).at(7) == 'n';
				level.at(13).at(7) == '!';
			}
	
	// Level
		public:
			std::vector<std::string> level{SIZE_Y};
			void initLevelelements();
			bool isALevelElement(char zeichen);
			
			void set_door(char &new_door);
			
		private:
			char wallSenkrecht = 254;
			char wallWaagerecht = 254;
			char border = 178;
			char muniElement = 8;
			char door = 127;
			char leer = ' ';
			std::pair<short, short> levelElementPos[43] = {
				// Waagerecht
				std::pair<short,short>( 4, 3),
				std::pair<short,short>( 5, 3),
				std::pair<short,short>( 6, 3),
				std::pair<short,short>( 7, 3),
				std::pair<short,short>( 8, 1),
				std::pair<short,short>( 9, 1),
				std::pair<short,short>(10, 1),
				std::pair<short,short>(11, 1),
				std::pair<short,short>(12, 1),
				std::pair<short,short>(13, 1),
				std::pair<short,short>(14, 1),
				std::pair<short,short>(15, 1),
				std::pair<short,short>(16, 1),
				std::pair<short,short>(17, 1),
				std::pair<short,short>(18, 1),
				std::pair<short,short>( 1, 5),
				std::pair<short,short>( 2, 5),
				std::pair<short,short>( 3, 5),
				std::pair<short,short>( 4, 5),
				std::pair<short,short>( 5, 5),
				std::pair<short,short>( 6, 5),
				std::pair<short,short>( 7, 5),
				std::pair<short,short>( 8, 5),
				std::pair<short,short>(10, 3),
				std::pair<short,short>(11, 3),
				std::pair<short,short>(14, 6),
				std::pair<short,short>(15, 6),
				std::pair<short,short>(12, 6),
				// Senkrecht
				std::pair<short,short>( 4, 1),
				std::pair<short,short>( 4, 2),
				std::pair<short,short>( 7, 2),
				std::pair<short,short>( 7, 1),
				std::pair<short,short>( 9, 5),
				std::pair<short,short>( 9, 4),
				std::pair<short,short>( 9, 3),
				std::pair<short,short>(11, 4),
				std::pair<short,short>(11, 5),
				std::pair<short,short>(11, 6),
				std::pair<short,short>(11, 7),
				std::pair<short,short>(13, 4),
				std::pair<short,short>(13, 5),
				std::pair<short,short>(13, 6),
				// Tür
				std::pair<short,short>(10, 4),
				// Munition
				//std::pair<short,short>( 8, 2);
			};

};

class Enemy {
	
};

class Console {
public:
	static void Log(std::string msg) {
		std::clog << "CLog: " << msg << std::endl;
	}
};

#endif

HTML:
<hr />
Data/lge.cpp
HTML:
<hr />
Code:
#include "lge.h"
#define WAIT std::cin.get();

// PLAYER:

Player::Player() : player(42), x(1), y(1), ziel_x(1), ziel_y(1), leben(3), munition(1) {
	system("CLS");
	//std::cout << "Obj. erzeugt!" << std::endl;
	initScreen();
	level.at(y).at(x) = player;
	print();
}
Player::Player(char player_icon) : player(player_icon), x(1), y(1), ziel_x(1), ziel_y(1) {
	
}
Player::Player(char player_icon, short x, short y) : player(player_icon), x(x), y(y), ziel_x(1), ziel_y(1) {
	
}

void Player::set_x(const short &xPos) {
	// Weitere Maßnahmen treffen!!!
	x = xPos;
}
void Player::set_y(const short &yPos) {
	// Weitere Maßnahmen treffen!!!
	y = yPos;
}
short Player::get_x() const {
	// Weitere Maßnahmen treffen!!!
	return x;
}
short Player::get_y() const {
	// Weitere Maßnahmen treffen!!!
	return y;
}
void Player::set_ziel_x(const short &xZielPos) {
	// Weitere Maßnahmen treffen!!!
	ziel_x = xZielPos;
}
void Player::set_ziel_y(const short &yZielPos) {
	// Weitere Maßnahmen treffen!!!
	ziel_y = yZielPos;
}
short Player::get_ziel_x() const {
	// Weitere Maßnahmen treffen!!!
	return ziel_x;
}
short Player::get_ziel_y() const {
	// Weitere Maßnahmen treffen!!!
	return ziel_y;
}
const char Player::get_playerICON() const {
	return player;
}

//-------------------------------------------------------------------------------------

	// Level:
	
void Player::set_door(char &new_door) {
	door = new_door;
}



void Player::initLevelelements() {
	//std::cout << "initLevelelements() begonnen!\n";WAIT
	// WAAGERECHT
	const int anzWaagerechte = 28;
	for ( int i = 0 ; i < anzWaagerechte ; ++i ) {
		level.at( levelElementPos[ i ].second ).at( levelElementPos[ i ].first ) = wallWaagerecht;
		//std::cout << "  waagerechte Wand erzeugt!\n";WAIT
	}
	// SENKRECHT
	const int anzSenkrechte = 14;
	for ( int i = anzWaagerechte ; i < ( anzWaagerechte + anzSenkrechte ) ; ++i ) {
		level.at( levelElementPos[ i ].second ).at( levelElementPos[ i ].first ) = wallSenkrecht;
		//std::cout << "  senkrechte Wand erzeugt!\n";WAIT
	}
	// Tür
	level.at( levelElementPos[ ((anzWaagerechte) + (anzSenkrechte)) ].second ).at( levelElementPos[ ((anzWaagerechte) + (anzSenkrechte)) ].first ) = door;
	//std::cout << "  Tuer erzeugt!\n";WAIT
	// Munition
	level.at( levelElementPos[ ( ((anzWaagerechte) + (anzSenkrechte)) + 1 ) ].second ).at( levelElementPos[ ( ((anzWaagerechte) + (anzSenkrechte)) + 1 ) ].first ) = muniElement;
	//std::cout << "initLevelelements() beendet!\n";WAIT
}

bool Player::isALevelElement(char zeichen) {
	if ( (zeichen == wallSenkrecht) || (zeichen == wallWaagerecht) || (zeichen == border) || (zeichen == door) ) return true;
	return false;
}


//-------------------------------------------------------------------------------------

	// Screen:

void Player::initScreen() {
	size_t levelSize = level.size();
	//std::cout << "initScreen() begonnen!\n";WAIT
	for ( int index = 0 ; index < levelSize ; ++index ) {
		for ( int i = 0 ; i < SIZE_X ; ++i ) {
			if ( index == 0 ) {
				level.at(index) += border;
				//std::cout << "  Border oben erzeugt!\n";WAIT
			}
			else if ( index == ( levelSize - 1 ) ) {
				level.at(index) += border;
				//std::cout << "  Border unten erzeugt!\n";WAIT
			}
			else if ( ( index != 0 ) && ( index != ( levelSize - 1 ) ) && ( i == 0 ) ) {
				level.at(index) += border;
				//std::cout << "  Border am linken Rand erzeugt!\n";WAIT
			}
			else if ( ( index != 0 ) && ( index != ( levelSize - 1 ) ) && ( i == ( SIZE_X-1 ) ) ) {
				level.at(index) += border;
				//std::cout << "  Border am rechten Rand erzeugt!\n";WAIT
			}
			else {
				level.at(index) += leer;
				//std::cout << "  Leerstelle erzeugt!\n";WAIT
			}
		}
	}
	//std::cout << "initScreen() beendet!\n";WAIT
	initLevelelements();
}

void Player::refreshScreen() {
	size_t levelSize = level.size();
	//std::cout << "refreshScreen() begonnen!\n";WAIT
	for ( int index = 0 ; index < levelSize ; ++index ) {
		for ( int i = 0 ; i < SIZE_X ; ++i ) {
			if ( index == 0 ) {
				level.at(index).at(i) = border;
				//std::cout << "  Border oben erzeugt!\n";WAIT
			}
			else if ( index == ( levelSize - 1 ) ) {
				level.at(index).at(i) = border;
				//std::cout << "  Border unten erzeugt!\n";WAIT
			}
			else if ( ( index != 0 ) && ( index != ( levelSize - 1 ) ) && ( i == 0 ) ) {
				level.at(index).at(i) = border;
				//std::cout << "  Border am linken Rand erzeugt!\n";WAIT
			}
			else if ( ( index != 0 ) && ( index != ( levelSize - 1 ) ) && ( i == ( SIZE_X-1 ) ) ) {
				level.at(index).at(i) = border;
				//std::cout << "  Border am rechten Rand erzeugt!\n";WAIT
			}
			else {
				level.at(index).at(i) = leer;
				//std::cout << "  Leerstelle erzeugt!\n";WAIT
			}
		}
	}
	//std::cout << "refreshScreen() beendet!\n";WAIT
	initLevelelements();
}

void Player::print() {
	system("CLS");
	for ( auto it : level ) std::cout << it << std::endl;
	std::cout << std::endl << " " << "X:" << x << " | " << "Y:" << y;//WAIT
}

//-------------------------------------------------------------------------------------

HTML:
<hr />
Data/lge/input.h
HTML:
<hr />
Code:
#ifndef INPUT_H
#define INPUT_H

#include <conio.h>
#include <utility>

class Input {
	char KEY=0;
	short keyX=0, keyY=0;
	std::pair<short, short> keyXY;
	bool end = false;
public:
	Input() : KEY(0), keyX(0), keyY(0), end(false) {}
	
	void set_keyX(const short &new_keyX=0) {
		keyX = new_keyX;
	}
	void set_keyY(const short &new_keyY=0) {
		keyY = new_keyY;
	}
	void set_keys(const short &new_keyX=0, const short &new_keyY=0) {
		keyX = new_keyX;
		keyY = new_keyY;
	}
	void make_keyXY() {
		keyXY = keyAnalyse();
	}
	
	std::pair<short, short> get_keyXY() const {
		return keyXY;
	}
	bool get_end() const {
		return end;
	}
	
	void waitForInput() {
		KEY = getch();
	}
	
	std::pair<short, short> keyAnalyse() {
		if      ( KEY == 119 /*w*/ ) --keyY;	
		else if ( KEY == 97 /*a*/ ) --keyX;
		else if ( KEY == 115 /*s*/ ) ++keyY;
		else if ( KEY == 100 /*d*/ ) ++keyX;
		else if ( KEY == 99 /*c*/ ) end = true;
		return std::make_pair(keyX, keyY);
	}
};

#endif

Ich hoffe, dass hier nicht zu viel (Mist) steht, hoffe aber, dass der Code evtl. helfen kann ...
 
Bin ich blind? Ich sehe in deinem ganzen Code weder eine Zuweisung von *, noch #.
 
In der Datei Data/lge.h lege ich die Zeichen fest (Zeile 76 - 81).
 
Hiermit möchte ich das Thema abschließen, da das Problem ja jetzt gelöst ist:
Vielen Dank für die schnellen Antworten!
Ich habe jetzt das const weggenommen, um die Variablen mit settern ändern zu können( void set_zeichen(char zeichen){zeichen = zeichen} ). Im Hauptprogramm ändere ich jetzt die Variablen ganz am Anfang durch diese Methode/n.

Jetzt geht es! PRIMA! Vielen Dank!

Ergänzung vom 13.07.2016 15:04 Uhr: Ich arbeite mit der Entwicklungsumgebung Orwell Dev-C++. Als ich zuerst "Rebuild All" und dann "Compile and Run" drückte(sonst lasse ich immer "Rebuild All" weg), änderten sich die Zeichen endlich!

Danke für die schnelle Hilfe!

-->> Trotz dem verstehe ich den Fehler immernoch nicht, was aber nicht weiter schlimm ist ...

Also nochmal vielen Dank für Eure Hile!
 
Zurück
Oben