Archief - [PROG][C++] Klasses en subklasses

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

/\quila

Legacy Member
Hoi,

Ik zit met een vrij basis probleem ivm klasses en subklasses, even de situatieschets.
Ik definieer:
1 hoofdklasse Gebouw; 3 Gebouw-subklasses Burcht, Kazerne en Boerderij.
In Gebouw steek ik de gemeenschappelijke atributen, in de subklasses de andere atributen.

Zo een gemeenschappelijk atribuut is bv de int Level. De Burcht moet het level van de andere twee gebouwen en zichzelf kunnen aanpassen. Daarvoor dacht ik binnen Burcht een functie aan te maken als volgt:
Upgrade( Gebouw UpgradeGebouw, int LevelsOmhoog, String^ Tijdstip )

De compiler protesteert nu als ik
Upgrade( Kazerne1, 2, "12:45" )
doorgeef. (cannot convert parameter 1 from 'Layout::Kazerne' to 'Layout::Gebouw')
Ik had gehoopt dat dit wel mogelijk ging zijn, vermits ik binnen de functie enkel aan de Gebouw attributen van Kazerne en aan de Burcht attributen zelf aanpassingen doe.
Ik had de functie ook liefst binnen Burcht gehouden, zo kan ik bijhouden hoeveel opdrachten er in wachtlijst staan etc.

Ik zou in dit geval eventueel meerdere functies kunnen definieren die telkens specifiek voor 1 type gebouw zijn, maar stel dat ik het zou uitbreiden, moet er toch een mogelijkheid zijn zodat ik niet 100x moet copy-pasten?

Iemand enige raad voor mij?


Mvg,
Aquila

KeaTs

Legacy Member
hum, kunt ge uw klasses es posten? Als Kazerne afleidt van Gebouw zou dat moeten lukken, dus waarschijnlijk ga je daar in de fout.

Ook, verander uw interface :

Upgrade( Gebouw & UpgradeGebouw, int LevelsOmhoog, String^ Tijdstip )

Uw niet-primitieve datatypes wilt ge passen by reference, niet by value ( ten eerste omdat je m wil aanpassen, ten tweede omdat reference veel performanter is, zoniet kopieert ie uw hele klasse )

/\quila

Legacy Member
Code:
	ref class Gebouw
	{
	private:
		int UpgradeLevel;

	public:
		int Index;
		int Level;
		int Village;
		int MinLvl;
		int MaxLvl;

	public:
		Gebouw( int Index, int Level, int Village, int MinLvl, int MaxLvl ) : Index( Index ), Level( Level ), Village( Village ), MinLvl( MinLvl ), MaxLvl( MaxLvl ) {}
		Gebouw() {}
		// Controle van upgrade mogelijkheden gebouw
		bool ControleerUpgrade()
		{
			...
		}
		// Level upgrade van het gebouw
		void Upgrade()
		{
			...
		}

		// Intervaltijd berekenen in ms tussen huidige tijd en een DateTime object
		int BerekenIntervaltijd( DateTime StartTijd )
		{
		        ...
                }
	};

Code:
	ref class Kazerne : public Gebouw
	{
		static double HFactor = 1.26;
		static double LFactor = 1.28;
		static double IFactor = 1.26;
		static double BFactor = 1.17;
		static int IniTijd = 900;
		static double TFactor = 1.2;
	public:
		Kazerne( int Level, int Village ) : Gebouw( 1, Level, Village, 0, 25) {
		}
	};

Het was oorspronkelijk eerst
void BouwOpdrachtToevoegen( Gebouw^ UpgradeGebouw, String^ TijdInvoer, bool Tijdstip, String^ BuildCode )
maar met al dat zoeken naar een mogelijke oplossing was dat idd verkeerd gelopen.
Het geheel is in managed C++ geschreven, maak gebruik van de windows forms.

killgore

Legacy Member
wil je de klasse burcht ook eens posten aub?

edit: ma ik zou met __gc en references werken zoals keats aangaf. Dunno of ref inheritance problemen geeft (deed wel een IDisposable extend als ik me niet vergis).

/\quila

Legacy Member
Oké, hier komt ie, ik heb enkel de functie laten staan waar het mij het meest om gaat.

Code:
	ref class Burcht : public Gebouw
	{
		// Timer toewijzen voor gebruik met bouwopdrachten
		static System::Windows::Forms::Timer^ OpdrachtenTimer = gcnew System::Windows::Forms::Timer;
		// Vector met hierin de starttijdstippen van de opdrachten voor het Burcht
		static vector<System::DateTime>^ OpdrachtenStartTijdstip = gcnew vector<System::DateTime>;

		// Spelgegevens
		static int Hout = 90;
		static int Leem = 80;
		static int Ijzer = 70;
		static int Bevolking = 5;
		static double HFactor = 1.26;
		static double LFactor = 1.275;
		static double IFactor = 1.26;
		static double BFactor = 1.17;
		static int IniTijd = 450;
		static double TFactor = 1.2;

	public:

		Burcht( int Level, int Village ) : Gebouw( 0, Level, Village, 1, 30) {
		}
		Burcht() {
		}
		void BouwOpdrachtToevoegen( Gebouw^ UpgradeGebouw, String^ TijdInvoer, bool Tijdstip, String^ BuildCode )
		{
			bool CorrectTijdstip = false;

			String^ Naam = "";
			
			//Gebouw UpgradeGebouw(1,12,115111,0,30);

			DateTime HuidigeTijd = DateTime::Now;
			DateTime StartTijd = HuidigeTijd;

			// Controle of gebouw beschikbaar is om te upgraden
			if( UpgradeGebouw->Level == -1 )
			{
				System::Windows::Forms::MessageBox::Show( "Gebouw niet beschikbaar" );
			}
			// Upgrade is mogelijk
			else
			{
				// Naam voor ListView bepalen
				switch( UpgradeGebouw->Index )
				{
				case 0: Naam = "Burcht"; break;
				case 1: Naam = "Kazerne"; break;
				case 2: Naam = "Boerderij"; break;
				default: System::Windows::Forms::MessageBox::Show( "Code error" ); break;
				}

				// Timerinstellingen
				// Input van de TextBox opsplitsen
				array<String^>^ SplitTijd = System::Text::RegularExpressions::Regex::Split( TijdInvoer, ":" );

				// Tijdstip == true -> Opdracht uitvoeren op ingevoerd tijdstip
				if( Tijdstip == true )
				{
					// Probleem met tijdstippen op de volgende dag !!!
					StartTijd = DateTime( HuidigeTijd.Year, HuidigeTijd.Month, HuidigeTijd.Day, Convert::ToInt32( SplitTijd[0] ), Convert::ToInt32( SplitTijd[1] ), Convert::ToInt32( SplitTijd[2] ) );
				}
				// Tijdstip == false -> Opdracht uitvoeren na bepaalde interval
				else
				{
					// Het aantal uren minuten en seconden uit de string invoer halen
					StartTijd = StartTijd.AddHours( Convert::ToInt32( SplitTijd[0] ) );
					StartTijd = StartTijd.AddMinutes( Convert::ToInt32( SplitTijd[1] ) );
					StartTijd = StartTijd.AddSeconds( Convert::ToInt32( SplitTijd[2] ) );
				}

				// Aantal milliseconden tot opdracht gegeven moet worden
				static int CountdownSeconden = BerekenIntervaltijd( StartTijd );

				// Eigenlijke toevoegen van opdracht indien er geen error werd opgeworpen
				if( CountdownSeconden >= 0 )
				{
					// De timer is nog niet gestart en er staan geen opdrachten te wachten
					if( OpdrachtenTimer->Enabled == false && OpdrachtenStartTijdstip->empty() == true && OpdrachtenURL->empty() == true )
					{
						// Toevoegen van starttijdstip aan de array
						OpdrachtenStartTijdstip->push_back( StartTijd );


						// Instellen van timer + starten
						OpdrachtenTimer->Interval = CountdownSeconden;
						OpdrachtenTimer->Start();

						// Opdracht juist weergeven in ListView
						int IndexNummer = 0;
						// Opdracht toevoegen aan ListView
						Layout::UpdateListView( IndexNummer, Naam, UpgradeGebouw->Index, StartTijd );
					}

					// De timer is reeds gestart
					else if( OpdrachtenTimer->Enabled == true )
					{
						// Aanmaken van iteratoren voor vectoren
						vector<System::DateTime>::iterator itMTT = OpdrachtenStartTijdstip->begin();

						// Overlopen van vectoren met tijdstippen
						for( int i = 0; itMTT != OpdrachtenStartTijdstip->end(); ++itMTT)
						{
							// De opdracht moet worden uitgevoerd voor het item gekoppeld aan huidige iterators
							if( System::DateTime::Compare( StartTijd, *itMTT ) < 0 )
							{
								// Toevoegen van StartTijdstip aan de vector op de correct plaats
								OpdrachtenStartTijdstip->insert( itMTT, StartTijd );

								// ListView updaten
								Layout::UpdateListView( i, Naam, UpgradeGebouw->Index, StartTijd );

								// Uit de for lus springen
								break;
							}

							// De opdracht moet als laatste worden uitgevoerd
							else if( System::DateTime::Compare( StartTijd, *itMTT ) > 0 && *itMTT == OpdrachtenStartTijdstip->back() )
							{
								// Zorgen dat de indexering correct is
								i++;

								// Toevoegen van StartTijdstip aan het einde van de vector
								OpdrachtenStartTijdstip->push_back( StartTijd );

								// Opdracht toevoegen aan ListView
								Layout::UpdateListView( i, Naam, UpgradeGebouw->Index, StartTijd );

								// Uit de for lus springen
								break;
							}

							// De opdracht valt gelijk met een andere opdracht
							else if( System::DateTime::Compare( StartTijd, *itMTT ) == 0 )
							{
								System::Windows::Forms::MessageBox::Show( "Gelijktijdige events, verander aub uitvoertijdstip" );
								break;
							}

							else 
							{
								// Indexering updaten
								i++;
							}
						}
					}
				}
			}
		}
		void BouwOpdrachtUpdaten()
		{
		}
		void BouwOpdrachtVerwijderen()
		{
		}
		// Timer van Burcht
		void OpdrachtenTimer_Tick( System::Object^ /*sender*/, System::EventArgs^ /*e*/ )
		{
			...
		}
	};
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan