Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > C/C++
You last visited: Today at 15:01

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Struct/MAP in struct speichern?

Discussion on Struct/MAP in struct speichern? within the C/C++ forum part of the Coders Den category.

Closed Thread
 
Old 09/14/2013, 11:58   #16


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
Verstehe ich nicht. Die Einführung des Schlüsselwortes "abstract" hat doch gerade bewirkt, dass man nicht mehr solche hässlichen Exceptions schmeißen muss mit "Not Implemented blabla". Der Compilier erzwingt die Implementation bei abgeleiteten Klassen und verbietet die Instanzierung der abstrakten Klasse. Wo soll da noch Raum sein, eine abstrakte Methode aufzurufen? Das muss schon gezielt mit Workarounds provoziert werden und da ist undefiniertes Verhalten für das Schwein doch genau das richtige. Eine saubere Fehlermeldung hat so jemand nicht verdient :<
MrSm!th is offline  
Old 09/14/2013, 12:50   #17
 
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
Und wenn du den Fehler finden musst (weil du für den entsprechenden Teil des Quellcodes verantwortlich bist) und sich herausstellt, das in einer (viel zu tiefen, aber nicht von dir entworfenen) Klassenhierarchie im Konstruktor / Destruktor einer Klasse eine virtuelle Methode aufgerufen wird, obwohl der Teil des Objekts notwendig für diese Implementierung dieser Methode nocht nicht existiert / schon zerstört wurde?
Tasiro is offline  
Old 09/14/2013, 13:36   #18


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
Virtuelle Methode im Konstruktor? Tasiro pls..
MrSm!th is offline  
Old 09/14/2013, 13:49   #19
 
Master674b's Avatar
 
elite*gold: 0
Join Date: Dec 2012
Posts: 255
Received Thanks: 110
Quote:
Originally Posted by MrSm!th View Post
Verstehe ich nicht. Die Einführung des Schlüsselwortes "abstract" hat doch gerade bewirkt, dass man nicht mehr solche hässlichen Exceptions schmeißen muss mit "Not Implemented blabla". Der Compilier erzwingt die Implementation bei abgeleiteten Klassen und verbietet die Instanzierung der abstrakten Klasse. Wo soll da noch Raum sein, eine abstrakte Methode aufzurufen? Das muss schon gezielt mit Workarounds provoziert werden und da ist undefiniertes Verhalten für das Schwein doch genau das richtige. Eine saubere Fehlermeldung hat so jemand nicht verdient :<
Hatte nen Fehler in nem library (luabind), das hat mir irgendwas zerfressen wenn noch shared referenzen übrig waren (), aber der lua_State geschlossen wurde. Lief dann im Endeffekt auf nen pure virtual function call raus. Wäre aber fast besser einfach zu crashen, dann hätte mein Filter nen Stacktrace machen können
Master674b is offline  
Old 09/15/2013, 01:09   #20
 
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
Quote:
Originally Posted by MrSm!th View Post
Virtuelle Methode im Konstruktor?
Den Konstruktor hatte ich nur erwähnt, weil es für diesen genauso wie für den Destruktor gilt. Es kann aber tatsächlich dazu kommen:
Code:
//B.h - Arbeitsgruppe B
class A;
class B {
	private:
		A a;

	public:
		B ();
		virtual void initialize () = 0;
};

//A.h - Arbeitsgruppe A
class A {
	private:
		B * b;

		void initialize_b ();

	public:
		A (B * b);
};

//A.cc
A::A (B * b) : b (b) {
	this->initialize_b ();
}

void A::initialize_b () {
	this->b->initialize ();
}

//B.cc
B::B () : a (this) {}
Jetzt werde ein B erstellt.
(Es ist ein Beispiel, nicht mehr.)

Der Aufruf einer virtuellen Funktion ist natürlich warscheinlicher in einem Destruktor.
Tasiro is offline  
Old 09/15/2013, 02:42   #21


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
Nur ist das Beispiel absolut nichtssagend, denn von B kannst du sowieso keine Instanz erstellen, da die Klasse abstrakt ist.
Eine erbende Klasse muss initialize implementieren und damit ist das Problem dann auch wieder verschwunden.

Code:
class A 
{
protected:
	int x;

public:

	A(int x)
		: x(x) {}

	int getX();

	virtual void initialize_x() = 0;
	virtual void uninitialize_x() = 0;
	virtual ~A();
};

int A::getX()
{
	return x;
}

A::~A()
{
        uninitialize_x();
};

class B : public A
{
public:
	B(int x);

	virtual void initialize_x();
	virtual void uninitialize_x();
	virtual ~B();
};

B::B(int x)
	: A(x)
{
	initialize_x();
}

void B::initialize_x()
{
	x *=2;
}

void B::uninitialize_x()
{
	x /= 2;
}

B::~B()
{
        //andere Aufräumarbeiten
	A::~A(); 
}

int main()
{
	A *binst = new B(10);   //exception: B::B() ruft A::initialize_x() auf, weil der B Teil der Instanz noch nicht existiert
	std::cout << binst->getX() << std::endl;
	delete binst;    //würde exception werfen, wenn das Programm so weit käme, weil A::~A() A::uninitialize_x() aufruft (da der B Teil bereits zerstört ist)
	return 0;
}
Dieses sinnlose Klassenbeispiel verdeutlicht schon eher, was du mir sagen willst.
Und darauf antwortete ich schon passend: Calls zu virtuellen Funktionen haben weder im Kon- noch im Destruktor etwas verloren.
MrSm!th is offline  
Old 09/15/2013, 11:50   #22
 
elite*gold: 0
Join Date: Jul 2013
Posts: 16
Received Thanks: 1
struct EventGift
{
DWORD dwID;
int nCount;
int nPercentage;
};
struct EventMonster
{
DWORD dwID;
int nInerval;
int nPercentage;
map<DWORD,EventGift> m_aEventGift;
};
class AutoEvent
{
public:
map<DWORD, EventMonster> m_aEventMonster;
AutoEvent();
~AutoEvent();

void ReadInc();
void Process();
};
xXGerdXx is offline  
Old 09/15/2013, 12:22   #23
 
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
Quote:
Originally Posted by MrSm!th View Post
Eine erbende Klasse muss initialize implementieren und damit ist das Problem dann auch wieder verschwunden.
Ist es nicht, zum Zeitpunkt der Konstruktion bzw. Destruktion eines Bs ist der this-Zeiger (für den Aufruf virtueller Funktionen) immer ein Zeiger auf ein B und nicht auf eine von B abgeleiteten Klasse, damit kann die aufgerufene Funktion statisch ermittelt werden (siehe §12.7.4).
Ähnliches Verhalten bei Rückruffunktionen, welche im Destruktor aufgerufen werden können und auf das eigentliche Objekt zugreifen können.

Dein Beispiel tut übrigens nicht das, was du sagst, initialize_x wird erst nach Erstellen aller Felder von B aufgerufen (aber vor dem Konstruktor einer von B abgeleiteten Klasse, in B sollte initialize_x mit final versehen werden - und mit override).

Wenn eine virtuelle Funktion im Destruktor (oder im Konstruktor...) aufgerufen wird, so geschieht das für gewöhnlich nicht absichtlich, aber es passiert hin und wieder.
Tasiro is offline  
Old 09/15/2013, 19:11   #24


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
Ich habe nichts dazu gesagt, wann initialize_x() in Bezug auf die Felder von B aufgerufen wird - ist mir schon klar, dass der Konstruktorrumpf nach deren Konstruktion aufgerufen wird.
Aber ich habe mich vertan, natürlich muss initialize_x() ebenfalls in den Konstruktor von A und nicht in den von B. Dann stimmt der Sinn des Beispiels auch wieder.

Quote:
Ist es nicht, zum Zeitpunkt der Konstruktion bzw. Destruktion eines Bs ist der this-Zeiger (für den Aufruf virtueller Funktionen) immer ein Zeiger auf ein B und nicht auf eine von B abgeleiteten Klasse, damit kann die aufgerufene Funktion statisch ermittelt werden (siehe §12.7.4).
Ähnliches Verhalten bei Rückruffunktionen, welche im Destruktor aufgerufen werden können und auf das eigentliche Objekt zugreifen können.
Ist es wohl, wenn man sich an die Regel hält, virtuelle Funktionen in Konstruktoren nicht aufzurufen.

Nun gut, für den Fall der Fälle kannst du natürlich die Funktion dennoch definieren und eine Exception schmeißen lassen. Durch sauberes Programmieren geht es imho aber auch ohne, alleine mit den Absicherungen des Compilers bei Verwendung von abstrakten Klassen.
MrSm!th is offline  
Old 09/15/2013, 20:40   #25
 
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
Quote:
Originally Posted by MrSm!th View Post
Ist es wohl, wenn man sich an die Regel hält, virtuelle Funktionen in Konstruktoren nicht aufzurufen.
Welches Problem ist verschwunden? Der Aufruf einer (da) rein virtuellen Funktion im Kon-/Destruktor? Wenn nichts aufgerufen wird, gibt es kein Problem, allerdings.
Dann dürfen also übergebene Funktionsobjekte nicht im Kon-/Destruktor aufgerufen werden, wenn es eine Klasse ist, die eine (u. U. private) Basisklasse mit einer (nicht notwendigigerweise rein) virtuellen Funktion hat?

Quote:
Originally Posted by MrSm!th View Post
Nun gut, für den Fall der Fälle kannst du natürlich die Funktion dennoch definieren und eine Exception schmeißen lassen. Durch sauberes Programmieren geht es imho aber auch ohne, alleine mit den Absicherungen des Compilers bei Verwendung von abstrakten Klassen.
Eine Klasse ist (in C++) dann abstrakt, wenn sie mindestens eine nicht überschriebene rein virtuelle Funktion hat. Ob eine rein virtuelle Funktion dann tatsächlich auch eine Implementierung hat, ist dafür irrelevant, sie bleibt rein virtuell. Deshalb sind es ja gerade diese Sonderfälle mit Konstruktor und Destruktor und unangebracht statischen Typkonvertierungen (und natürlich Parallelität), welche zu solchen Aufrufen führen.
Tasiro is offline  
Old 09/17/2013, 21:43   #26
 
elite*gold: 4
Join Date: Mar 2010
Posts: 3,148
Received Thanks: 1,535
mein goot ist der thread ausgeatet, habs nun geschafft. lag wirklich an dem ZeroMemory

danke!

#closerrequest
Jopsi332 is offline  
Old 09/19/2013, 22:40   #27

 
xxfabbelxx's Avatar
 
elite*gold: 900
Join Date: Apr 2009
Posts: 14,976
Received Thanks: 11,388
closed on request
xxfabbelxx is offline  
Closed Thread


Similar Threads Similar Threads
[help] new, delete, struct
01/23/2013 - C/C++ - 9 Replies
Well, i have a structure, input and output functions, to get some data, now i would like to make the following: -the user inputs a number (for which i need a dynamic memory reservation) -and that number declares how many times the input should loop) so for example the use puts in 4; it will run the input function 4 times he can tpye in stuff for 4 different companyes or w/e ... same with the output Here is waht i ahev for now:
Struct Allokieren ?
12/08/2012 - C/C++ - 11 Replies
Hallo, Ich arbeite mich gerade durch das Buch C++ A - Z und bin gerade bei den Structuren, so jetzt habe ich mir als beispiel ein kleines (Telefon Buch) gemacht ganz simpel (Vorname, Nachname, Geschlecht, Nummer) Code #include "stdafx.h" using namespace std;
struct and classes
08/03/2012 - CO2 Programming - 6 Replies
took about 50 pages reading about difference between structs and classes , so i thought it's good idea to sum up this for whoever want to get it with a spoon , feel free to correct or add information at struct cannot have instance field initializers in structs struct time { private int x = 5; // compile-time error } Structs cannot contain explicit parameterless constructors struct time {
[c++] struct
08/25/2011 - C/C++ - 2 Replies
Kann closed werden. sry
Packet Struct's
05/02/2009 - Kal Online - 30 Replies
Mir war langweilig hier nen beispiel wie ihr wie ich finde alles bischen besser aussehn lassen könnt :P struct PacketsSend { DWORD VersionCheck; DWORD Login; DWORD Ping; DWORD Skill; DWORD Chat;



All times are GMT +2. The time now is 15:01.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.