Klassen und Instanzen



  • Moin,

    da ich neu in c++ bin sorry falls es eher doof ist X-D.
    Ich versuche eine Klasse zu instanzieren, allerdings scheint es immer nur eine Instanz dieser Klasse zu geben. Die Klasse:

    class Zahler
    {
    protected:
    
    public:
    	Zahler();
    	Zahler(int ukap, int up);
    	~Zahler();
    	bool darf();
    	void aktuaktwert();
    	void init(int ukap, int up);
    	void add();
    
    private:
    	int kap;
    	int aktrwert;
    	int aktzeit;
    
    };
    

    Das Anlegen der Instanzen sieht dann folgender maßen aus:

    Zahler gesamt(6144,833);
    Zahler in1(2048,833);
    Zahler in2(2048,833);
    Zahler in3(2048,833);
    Zahler in4(2048,833);
    Zahler in5(2048,833);
    

    Leider ist gesamt die gleiche Instanz wie in1 oder in2. Ich hab keine Ahnung wieso.



  • Wie kommst du auf die Idee das die gleich wären?



  • das würd ich auch gern wissen. was verstehst du unter gleich? ja, sie sind alle instanzen der selben klasse. worauf willst du hinaus?



  • die Funktion add()

    void Zahler::add()
    {
    	akt = akt + 50;
    }
    

    und die Funktion darf()

    bool Zahler::darf()
    {
    	bool ret = false;
    	aktuaktwert();
    	EV << "Der wert des Zähles wird gepürft er ist" << akt << "\n";
    	if ((akt + 50) < kap)
    	{
    		//akt = akt + 50; // annahme alle Pakete sind 50 kByte groß!
    		ret = true;
    	}
    	return ret;
    }
    

    Ich rufe auf

    if(gesamt.darf()& in2.darf())
    		{
    			gesamt.add();
    			in2.add();
    

    Dies geschieht mehrmals hintereinander jeweils für ein anderes inx .

    Die Ausgabe von darf() zeigt mir dann immer an:

    Der wert des Zähles wird gepürft er ist300
    Der wert des Zähles wird gepürft er ist300

    das dürfte aber nicht sein. Sondern der Wert vom zweiten müsste niedriger sein. In diesem Fall eigentlich gleich 0.


  • Mod

    Bist du dir denn sicher, dass die zweite Ausgabe auch zu der zweiten Instanz gehört? Das zweite darf wird nämlich gar nicht ausgeführt, falls das erste schon false sein sollte.

    Gib doch mal ein vollständiges compilierbares Beispiel für dein Problem. Im Moment ist alles nur geraten, da du zu wenige Informationen gibst.



  • Was ist denn 'akt'? Ein Member jedenfalls nicht...
    Also was globales?



  • Ja bin mir relativ sicher das es eigentlich die 2te Instanz sein sollte. Das kompilierbare Beispiel wird schwierig da es sich um ein Omnet++ Projekt handelt.

    Zum Programm ablauf zuerst wird das Gateway initalisiert, danach wird für jede msg die ankommt die Funktion handleMessage(cMessage *msg) aufgerufen.

    #include <string.h>
    #include <omnetpp.h>
    #include <Zahler.h>
    #include <message_m.h>
    
    using namespace std;
    
    class Gateway : public cSimpleModule
    {
    private:
    	int counter;
    protected:
    	virtual void initialize();
    	virtual void handleMessage(cMessage *msg);
    };
    
    Define_Module(Gateway);
    
    Zahler gesamt(6144,833);
    Zahler in1(2048,833);
    Zahler in2(2048,833);
    Zahler in3(2048,833);
    Zahler in4(2048,833);
    Zahler in5(2048,833);
    
    void Gateway::initialize()
    {
    	EV << "Init";
    }
    
    void Gateway::handleMessage(cMessage *msg)
    {
    	int src, dest;
    	EV << "Received message '" << msg->getName() <<"\n";
    	Paket *ttmsg = check_and_cast<Paket *>(msg);
    
    	src = ttmsg->getSource();
    	dest = ttmsg->getDest();
    	EV << "Soruce:  '" << src <<"\n";
    	EV << "Dest:  '" << dest <<"\n";
    
    	Paket *ruckmsg = new Paket("ruckmeldung");
    
    	switch(src)
    	{
    	case 1 :
    		if(gesamt.darf()& in1.darf())
    		{
    			gesamt.add();
    			in1.add();
    			send(msg, "outz");
    			EV << "Nachricht abgeschickt an Ziel von in1";
    		}
    		else
    		{
    			EV << "Nachricht an Ziel von in1 wurde verworfen";
    		}
    		send(ruckmsg, "out1");
    		break;
    
    	case 2 :
    		if(gesamt.darf()& in2.darf())
    		{
    			gesamt.add();
    			in2.add();
    			send(msg, "outz");
    			EV << "Nachricht abgeschickt an Ziel von in2";
    		}
    		else
    		{
    			EV << "Nachricht an Ziel von in2 wurde verworfen";
    		}
    		send(ruckmsg, "out2");
    		break;
    
    	case 3 :
    		if(gesamt.darf()& in3.darf())
    		{
    			gesamt.add();
    			in3.add();
    			send(msg, "outz");
    			EV << "Nachricht abgeschickt an Ziel von in3";
    		}
    		else
    		{
    			EV << "Nachricht an Ziel von in3 wurde verworfen";
    		}
    		send(ruckmsg, "out3");
    		break;
    
    	case 4 :
    		if(gesamt.darf()& in4.darf())
    		{
    			gesamt.add();
    			in4.add();
    			send(msg, "outz");
    			EV << "Nachricht abgeschickt an Ziel von in4";
    		}
    		else
    		{
    			EV << "Nachricht an Ziel von in4 wurde verworfen";
    		}
    		send(ruckmsg, "out4");
    		break;
    
    	case 5 :
    		if(gesamt.darf()& in5.darf())
    		{
    			gesamt.add();
    			in5.add();
    			send(msg, "outz");
    			EV << "Nachricht abgeschickt an Ziel von in5";
    		}
    		else
    		{
    			EV << "Nachricht an Ziel von in5 wurde verworfen";
    		}
    		send(ruckmsg, "out5");
    		break;
    	}
    }
    
    #include <string.h>
    #include <Zahler.h>
    #include <omnetpp.h>
    
    int kap;
    int p;
    float akt;
    int64 letzte;
    int d;
    
    Zahler::Zahler()
    {
    
    }
    Zahler::Zahler(int ukap,int up )
    {
    	kap = ukap;
    
    	if ((up > 0) && (up < 1001))
    	{
    		p = up;
    	}
    	else
    	{
    		p = 1;
    		EV << "p hat die falschen grenzen!!! p wurde auf 1 gesetzt!";
    	}
    	letzte = SimTime::getScale();
    	d= 10; // Anzahl der Dekrementierungen pro Sekunde, !!!!muss immer 1000 ganz zahlig teilen!!!!!!!!
    	akt = 0;
    }
    Zahler::~Zahler()
    {
    }
    void Zahler::init(int ukap, int up)
    {
    	kap = ukap;
    
    	if ((up > 0) && (up < 1001))
    	{
    		p = up;
    	}
    	else
    	{
    		p = 1;
    		EV << "p hat die falschen grenzen!!! p wurde auf 1 gesetzt!";
    	}
    	letzte = SimTime::getScale();
    	d= 10; // Anzahl der Dekrementierungen pro Sekunde, !!!!muss immer 1000 ganz zahlig teilen!!!!!!!!
    	akt = 0;
    }
    
    void Zahler::aktuaktwert()
    {
    	int64 jetzt;
    	int64 diff;
    
    	jetzt = SimTime::getScale();
    
    	diff = jetzt - letzte;
    
    	while (diff > (1000/d))
    		{
    			akt = akt - p * kap / 1000 / d;
    			EV << "der Zähler wurde reduziert" << akt << "\n";
    
    			if (akt < 0)
    			{
    				akt = 0;
    				while (diff > (1000/d)) // akt 0 kann schleife beschleunigen
    				{
    					diff = diff - (1000/d);
    				}
    			}
    
    			diff = diff - (1000/d);
    		}
    
    	letzte = jetzt-diff; // in diff ist jetzt die anzahl der ms die nicht in das zeitintervall gepasst haben
    }
    
    bool Zahler::darf()
    {
    	bool ret = false;
    	aktuaktwert();
    	EV << "Der wert des Zähles wird gepürft er ist" << akt << "\n";
    	if ((akt + 50) < kap)
    	{
    		//akt = akt + 50; // annahme alle Pakete sind 50 kByte groß!
    		ret = true;
    	}
    	return ret;
    }
    
    void Zahler::add()
    {
    	akt = akt + 50;
    }
    


  • Ok, mir ist gerade aufgefallen das die Zahler.h nicht ganz ok war. Dazu hab ich aber jetzt noch mal ne Frage. Wie bekomme ich ein int64 in einen Header?

    Danke euch 🙂



  • Wie vermutet ist 'akt' also global.

    Der wert des Zähles wird gepürft er ist300
    Der wert des Zähles wird gepürft er ist300

    das dürfte aber nicht sein. Sondern der Wert vom zweiten müsste niedriger sein. In diesem Fall eigentlich gleich 0.

    Nein, da 'akt' halt kein Member, sondern eine globale Variable ist und daher unabhängig von den einzelnen Zahler-Instanzen.



  • Der_Ernst schrieb:

    Wie bekomme ich ein int64 in einen Header?

    Indem du den Header einbindest, der definiert was ein int64 überhaupt ist. Ein Standard-Datentyp ist das nämlich nicht.



  • Danke,

    solangsam begreife ich auch c++, zumindest welche variable was macht und wo definiert ist. Es ist schon sehr verwirrend aber irgendwie auch recht nützlich.

    Bezüglich dem int64 konnte ich über

    #include <inttypes.h>

    ihn dann auch im header einbinden.



  • Der_Ernst schrieb:

    if(gesamt.darf()& in1.darf())
    

    Der logische Und-Operator in C++ ist &&, nicht &. Zum Beispiel hat && Shortcut-Semantik, wertet also den zweiten Operanden nur aus, falls der erste true ist.

    Der_Ernst schrieb:

    Bezüglich dem int64 konnte ich über
    #include <inttypes.h>
    ihn dann auch im header einbinden.

    Das ist aber kein C++-Header (im Sinne von Standard-C++, auf das man spätestens im Bezug auf Portabilität achten sollte).


Log in to reply