C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

virtueller new-Operator geht nicht

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Georg Maaß
Guest





PostPosted: Sat Dec 06, 2003 5:19 pm    Post subject: virtueller new-Operator geht nicht Reply with quote



Ich hatte vor, eine Basis-Klasse als Interface zu entwerfen, deren
abgeleitete Klassen sich nur durch die Art der Speicher-Allokierung
unterscheiden sollten. Als eine Art der Speicher-Allokierung ist shared
memory angedacht. Dazu wollte ich Destruktor und new-Operator virtuell
machen, damit die Speicherverwaltung sich möglichst nah bei den
betreffenden Strukturen befindet.

Beim new-Operator geht das mit dem virtual aber nicht.

error: `operator new' cannot be declared virtual, since it is always static

Die betreffende Klasse hat ausschließlich protected Konstruktoren, kann
also nur von einer als friend deklarierten Factory-Klasse erzeugt
werden. Kann man unter dem Aspekt, daß shared memory genutzt werden
soll, den Allokationsmechanismus auch in der Factory-Klasse unterbringen?

Im Augenblick ist keine Implementierung von shared memory beabsichtigt,
sondern lediglich eine solche Deklaration der Schnittstelle, daß diese
einer späteren Implementierung von shared memory-Techniken nicht im Wege
steht.

Kann man eigentlich solche Allokatoren, wie sie für die STL-Templates
benutzt werden auch für normale Klassen verwenden? Wenn ja, wie macht
man das?

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Ludwig Pumberger
Guest





PostPosted: Sun Dec 07, 2003 1:44 pm    Post subject: Re: virtueller new-Operator geht nicht Reply with quote



Georg Maaß schrieb:

Quote:
Ich hatte vor, eine Basis-Klasse als Interface zu entwerfen, deren
abgeleitete Klassen sich nur durch die Art der Speicher-Allokierung
unterscheiden sollten. Als eine Art der Speicher-Allokierung ist shared
memory angedacht. Dazu wollte ich Destruktor und new-Operator virtuell
machen, damit die Speicherverwaltung sich möglichst nah bei den
betreffenden Strukturen befindet.

Beim new-Operator geht das mit dem virtual aber nicht.

error: `operator new' cannot be declared virtual, since it is always
static

Naja die Fehlermeldung ist ja auch recht aussagekräftig oder? Es hat auch
keinen Sinn new virtuell machen zu wollen, weil new ja bei der
Objekterzeugung verwendet wird und da ist der exakte Typ ohnehin bekannt.
Einen C'tor kannst du schliesslich genausowenig virtuell machen.

Quote:
Die betreffende Klasse hat ausschließlich protected Konstruktoren, kann
also nur von einer als friend deklarierten Factory-Klasse erzeugt
werden. Kann man unter dem Aspekt, daß shared memory genutzt werden
soll, den Allokationsmechanismus auch in der Factory-Klasse unterbringen?

Da gehört dieser Aspekt IMO auch hin. Durch Austauschen der Factory
bekommst du ein anderes Speichermodell.

Quote:
Im Augenblick ist keine Implementierung von shared memory beabsichtigt,
sondern lediglich eine solche Deklaration der Schnittstelle, daß diese
einer späteren Implementierung von shared memory-Techniken nicht im Wege
steht.

Wenn du ohnehin eine Factory hast kannst du durch Ableiten jederzeit
andere Möglichkeiten einbauen.

Quote:
Kann man eigentlich solche Allokatoren, wie sie für die STL-Templates
benutzt werden auch für normale Klassen verwenden? Wenn ja, wie macht
man das?

STL-Templates sind "normale" Klassen. Wenn du mit normal nicht-template
meinst, sicher:

std::allocator<int> intAlloc;
int *p = intAlloc.allocate(10);
intAlloc.deallocate(p, 10);

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Georg Maaß
Guest





PostPosted: Sun Dec 07, 2003 5:09 pm    Post subject: Re: virtueller new-Operator geht nicht Reply with quote



Ludwig Pumberger wrote:
Quote:
Naja die Fehlermeldung ist ja auch recht aussagekräftig oder?

Deshalb habe ich ja auch nicht gefragt, warum es nicht geht, sondern
nach Alternativen gefragt.

Quote:
Es hat
auch keinen Sinn new virtuell machen zu wollen, weil new ja bei der
Objekterzeugung verwendet wird und da ist der exakte Typ ohnehin
bekannt.

Wenn der new-Operator des Objektes regeln soll, wie Speicher für das
Objekt selbst anzufordern ist, dann gebe ich Dir recht. Ich dachte,
damit regeln zu können, wie das Objekt selbst Speicher für andere
Objekte anfordern soll, die durch Methoden des Objektes erzeugt werden.
Das von der Factory erzeugte Objekt arbeitet nämlich ebenfalls als Factory.

Quote:
Da gehört dieser Aspekt IMO auch hin. Durch Austauschen der Factory
bekommst du ein anderes Speichermodell.

und verliere die Polimorphy

Aber nur für das Hüllobjekt. Dieses aber weiß nichts davon, daß es jetzt
ein anderes Objekt ist und wird weiterhin seine eigenen Daten
konventionell anfordern, obwohl es ebenfalls die andere Allokation
verwenden müßte.

Das kann also nur dann aufgehen, wenn das von der Factory erzeugte
Objekt nicht seinerseits Freispeicher anfordert, sondern ausschließlich
"automatische" Member besitzt, die nicht ihrerseist einen Allokator
benötigen (z.B. map). Das trifft aber auf mein Objekt nicht zu, sondern
es enthält seineseits Zeiger und Maps und Vektoren und Listen.

Das Objekt zur Darstellung ganzer DOM-Bäume ist zu komplex für die
Verwendung in einer shared memory Umgebung.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Tibor Pausz
Guest





PostPosted: Sun Dec 07, 2003 9:52 pm    Post subject: Re: virtueller new-Operator geht nicht Reply with quote

Georg Maaß <georg (AT) bioshop (DOT) de> wrote:

Quote:
Aber nur für das Hüllobjekt. Dieses aber weiß nichts davon, daß es jetzt
ein anderes Objekt ist und wird weiterhin seine eigenen Daten
konventionell anfordern, obwohl es ebenfalls die andere Allokation
verwenden müßte.

Warum achst Du es nicht ähnlich wie die STL Klassen, mit eigenem Traits
Template Class oder wenn es polymorph sein soll mit einer eigenen
Klasse, die eine virtuellen member new_obj o.ä. besitzt?

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Ludwig Pumberger
Guest





PostPosted: Mon Dec 08, 2003 6:23 pm    Post subject: Re: virtueller new-Operator geht nicht Reply with quote

Georg Maaß schrieb:

Quote:
Wenn der new-Operator des Objektes regeln soll, wie Speicher für das
Objekt selbst anzufordern ist, dann gebe ich Dir recht. Ich dachte,
damit regeln zu können, wie das Objekt selbst Speicher für andere
Objekte anfordern soll, die durch Methoden des Objektes erzeugt werden.
Das von der Factory erzeugte Objekt arbeitet nämlich ebenfalls als
Factory.

Da gehört dieser Aspekt IMO auch hin. Durch Austauschen der Factory
bekommst du ein anderes Speichermodell.

und verliere die Polimorphy

Versteh ich nicht. Die Polymorphie kommt ja durch die virtuellen
Factorymethoden zustande.

Quote:
Aber nur für das Hüllobjekt. Dieses aber weiß nichts davon, daß es jetzt
ein anderes Objekt ist und wird weiterhin seine eigenen Daten
konventionell anfordern, obwohl es ebenfalls die andere Allokation
verwenden müßte.

Das kann also nur dann aufgehen, wenn das von der Factory erzeugte
Objekt nicht seinerseits Freispeicher anfordert, sondern ausschließlich
"automatische" Member besitzt, die nicht ihrerseist einen Allokator
benötigen (z.B. map). Das trifft aber auf mein Objekt nicht zu, sondern
es enthält seineseits Zeiger und Maps und Vektoren und Listen.

Ah, jetzt kapier ich wo das Problem liegt.

Ein Weg wäre eventuell von virtuellen Schnittstellen Templateklassen
abzuleiten die einen Allokator als Parameter haben und diesen intern zur
Objekterzeugung benutzen. Dann könntest du von einer Basisfactory analog
eine Templatefactory ableiten die für einen Allokator die nötigen
konkreten Instanzen erzeugt.

Also in etwa so:

class Base
{
....
};

class X : public Base
{
....
};

template <typename A>
class ImplementX : public X
{
.... //Schnittstelle von X mittels A umsetzen
};

class Factory
{
public:
virtual ~Factory(){}
virtual X *createX(...) = 0;
};

template <typename A>
class ImplementFactory : public Factory
{
public:
virtual X *createX(...)
{
return new ImplementX<A>(...);
}
};

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Georg Maaß
Guest





PostPosted: Sat Dec 13, 2003 1:54 pm    Post subject: Re: virtueller new-Operator geht nicht Reply with quote

Ludwig Pumberger wrote:
Quote:
Georg Maaß schrieb:

Wenn der new-Operator des Objektes regeln soll, wie Speicher für das
Objekt selbst anzufordern ist, dann gebe ich Dir recht. Ich dachte,
damit regeln zu können, wie das Objekt selbst Speicher für andere
Objekte anfordern soll, die durch Methoden des Objektes erzeugt
werden. Das von der Factory erzeugte Objekt arbeitet nämlich ebenfalls
als Factory.

Da gehört dieser Aspekt IMO auch hin. Durch Austauschen der Factory
bekommst du ein anderes Speichermodell.


und verliere die Polimorphy


Versteh ich nicht. Die Polymorphie kommt ja durch die virtuellen
Factorymethoden zustande.

Aber nur für das Hüllobjekt. Dieses aber weiß nichts davon, daß es
jetzt ein anderes Objekt ist und wird weiterhin seine eigenen Daten
konventionell anfordern, obwohl es ebenfalls die andere Allokation
verwenden müßte.

Das kann also nur dann aufgehen, wenn das von der Factory erzeugte
Objekt nicht seinerseits Freispeicher anfordert, sondern
ausschließlich "automatische" Member besitzt, die nicht ihrerseist
einen Allokator benötigen (z.B. map). Das trifft aber auf mein Objekt
nicht zu, sondern es enthält seineseits Zeiger und Maps und Vektoren
und Listen.


Ah, jetzt kapier ich wo das Problem liegt.

Ein Weg wäre eventuell von virtuellen Schnittstellen Templateklassen
abzuleiten die einen Allokator als Parameter haben und diesen intern zur
Objekterzeugung benutzen. Dann könntest du von einer Basisfactory analog
eine Templatefactory ableiten die für einen Allokator die nötigen
konkreten Instanzen erzeugt.

Das mag vielleicht eine Lösung des Problems sein, nur verstehe ich es
nicht und kann es daher nicht beurteilen, ob es das Problem löst oder nicht.



Quote:

Also in etwa so:

class Base
{
...
};

class X : public Base
{
...
};

template <typename A
class ImplementX : public X
{
... //Schnittstelle von X mittels A umsetzen
};

class Factory
{
public:
virtual ~Factory(){}
virtual X *createX(...) = 0;
};

template class ImplementFactory : public Factory
{
public:
virtual X *createX(...)
{
return new ImplementX }
};


Was ist das A? Ist das der Allokator? Ich verstehe den Template-Code
nicht. Was meinst mit "Schnittstelle von X mittels A umsetzen"? Die
Schnittstelle ist ja wohl in Base festgelegt, und X muß sie implementieren

Wenn X startk vereinfacht z.B. so aussieht:

class X: public BaseX
{
int i;
std::string s;
}

Wenn nun X mit einer bestimmten Speicher-Allokation erzeugt wird, dann
muß garantiert sein, daß auch alle zu der Eigenschaft s gehörenden Daten
in dem für X allokierten Speicher liegen. Es darf also nicht sein, daß
etwa X im shared memory angelegt wird, s den Speicher für seine
Buchstaben aber from normalen Heap anfordert.

Schlimmer noch, wenn das X so aussieht:

class sharedX: public BaseX
{
std::map<std::string, BaseX *> Xmap;
}

class heapX: public BaseX
{
std::map<std::string, BaseX *> Xmap;
}

und die BaseX'e in der Xmap von Methoden von X erzeugt werden, wobei ein
X, das im Heap angelegt wurde (heapX) sowohl solche X'e erzeugen darf,
die ebenfalls im Heap liegen (heapX), als auch solche, die im shared
memory liegen (sharedX), umgekehrt aber X'e, die im shared memory liegen
(sharedX) ausschließlich X'e vom Typ sharedX in seine Xmap einspeisen
darf. Die sharedX'e müssen also nicht nur das grunsätzliche Verfehen
kenne, wie man shared memory anfordert, sondern sie müssen auch wissen,
zu welchem shared memory sie gehören, um für die von ihnen erzeugten
Objekte Speicher aus dem gleichen Speicherbereich anzuforden.

Bei Erzeugung eines dieser X'e ist nicht bekannt, wieviel Speicher das X
verbrauchen wird, da das X ja während der Lebenszeit wachsen und
schrumpfen kann. Im Heap ist das alles kein Problem, weil der Speicher
dort nur von dem gelsen wird, der ihn auch befüllt hat, so daß der das
Chaos kennt, das er angerichtet hat.

Beim shared memory ist das viel kompizierter. Zum einen darf es nur
einen einzigen shared memory Block geben, der hinreichend groß ist, um
Platz für alle (mehrere Tausend X'e) zu bieten, die zu Lebzeiten ständig
ihre Größe und Anzahl variieren können. Die Verwaltungsinfos für den
shared memory sowie die Locks müssen also ebenfalls in diesem liegen,
damit die Applikatione, die sich den shared memory teilen, instantan mit
einander kommunizieren können.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Ludwig Pumberger
Guest





PostPosted: Sun Dec 14, 2003 10:50 am    Post subject: Re: virtueller new-Operator geht nicht Reply with quote

Georg Maaß schrieb:

Quote:

Also in etwa so:

class Base
{
...
};

class X : public Base
{
...
};

template <typename A
class ImplementX : public X
{
... //Schnittstelle von X mittels A umsetzen
};

class Factory
{
public:
virtual ~Factory(){}
virtual X *createX(...) = 0;
};

template class ImplementFactory : public Factory
{
public:
virtual X *createX(...)
{
return new ImplementX }
};


Was ist das A? Ist das der Allokator? Ich verstehe den Template-Code
nicht. Was meinst mit "Schnittstelle von X mittels A umsetzen"? Die
Schnittstelle ist ja wohl in Base festgelegt, und X muß sie
implementieren

A soll der Allokator sein. Base ist die "normale" Basis. X ist von Base
abgeleitet. Aber alles in X was irgendetwas mit Speicherverwaltung zu tun
hat wird ausgelagert. Das Template implementiert X für einen bestimmten
Allokator. Auf Base kannst du natürlich auch verzichten. Ich ging aber
davon aus dass deine Klassen innerhalb einer Hierarchie liegen.

Quote:
Wenn X startk vereinfacht z.B. so aussieht:

class X: public BaseX
{
int i;
std::string s;
}

Wenn nun X mit einer bestimmten Speicher-Allokation erzeugt wird, dann
muß garantiert sein, daß auch alle zu der Eigenschaft s gehörenden Daten
in dem für X allokierten Speicher liegen. Es darf also nicht sein, daß
etwa X im shared memory angelegt wird, s den Speicher für seine
Buchstaben aber from normalen Heap anfordert.

X soll KEINE Daten enthalten.

Erweitertes Beispiel:

class X
{
public:
virtual ~X(){}
virtual void addInt(int i) = 0;
virtual int getInt(std::size_t index) const = 0;
};

template <typename A = std::allocator
class ImplementX
{
std::vector<int, A> storage_;
public:
void addInt(int i){storage_.push_back(i);}
int getInt(std::size_t index) const
{
assert(index < storage_.size());
return storage_[index];
}
};

Jetzt kannst z.B. auch ein ImplementX erzeugen und
über einen X * verwenden. Um andere Dinge zu allokieren kannst du rebind
verwenden. Du musst in der Schnittstelle natürlich aufpassen. Einen
std::string können deine Basismethoden z.B. nicht zurückgeben. Hier
würdest du eine wohl oder übel einen eigenen (polymorphen) Wrapper
brauchen.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Georg Maaß
Guest





PostPosted: Sun Dec 14, 2003 2:59 pm    Post subject: Re: virtueller new-Operator geht nicht Reply with quote

Ludwig Pumberger wrote:
Quote:
Jetzt kannst z.B. auch ein ImplementX<SharedAllokator erzeugen
und über einen X * verwenden. Um andere Dinge zu allokieren kannst du
rebind verwenden. Du musst in der Schnittstelle natürlich aufpassen.
Einen std::string können deine Basismethoden z.B. nicht zurückgeben.
Hier würdest du eine wohl oder übel einen eigenen (polymorphen) Wrapper
brauchen.
Das läuft dann auf ein elendiges Hin und Herkopieren hinaus, weil ja der

phayikalische Aufbau eines std::string nicht bekannt ist, so daß ein
brutales Casten allenfalls zufällig funktionieren würde. Wenn aber jeder
zugriff zu einem Kopiervorgang führt, dann ist der Zweck des Konzepts
vollständig verfehlt.

Ganz offenbar artet die Simulation dessen, was C++ nicht kann, in C++
derart aus, daß es sich nicht lohnt, es in C++ zu versuchen, sondern
effizienter ist, sich nach einer Sprache umzusehen, die das von Natur
aus kann.

--
Georg Maaß - bioshop.de D-76227 Karlsruhe, Westmarkstraße 82
HTML, XML / JavaScript, C++, Java, PHP, VB / CGI, JSP, ASP, ASP.net
- The ultimate DHTML engine: http://gml-modul.sourceforge.net -
http://sourceforge.net/projects/gml-modul

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Ludwig Pumberger
Guest





PostPosted: Sun Dec 14, 2003 5:43 pm    Post subject: Re: virtueller new-Operator geht nicht Reply with quote

Georg Maaß schrieb:

Quote:
Jetzt kannst z.B. auch ein ImplementX<SharedAllokator erzeugen
und über einen X * verwenden. Um andere Dinge zu allokieren kannst du
rebind verwenden. Du musst in der Schnittstelle natürlich aufpassen.
Einen std::string können deine Basismethoden z.B. nicht zurückgeben.
Hier würdest du eine wohl oder übel einen eigenen (polymorphen) Wrapper
brauchen.
Das läuft dann auf ein elendiges Hin und Herkopieren hinaus, weil ja der
phayikalische Aufbau eines std::string nicht bekannt ist, so daß ein
brutales Casten allenfalls zufällig funktionieren würde. Wenn aber jeder
zugriff zu einem Kopiervorgang führt, dann ist der Zweck des Konzepts
vollständig verfehlt.

Nein Hin- und Herkopieren musst du nicht du brauchst nur eine rein
virtuelle Basisklasse Klasse String die die gesamte Schnittstelle in Form
abstrakter Methoden bietet. Davon leitest du dann eine Templateklasse ab
die intern std::basic_string mit dem Allokator instaniiert und die
Schnittstelle implementiert. Eine recht einfache Möglichkeit um
Compilezeitpolymorphie in Form von Templates in Laufzeitpolymorphie
umzusetzen.

Quote:
Ganz offenbar artet die Simulation dessen, was C++ nicht kann, in C++
derart aus, daß es sich nicht lohnt, es in C++ zu versuchen, sondern
effizienter ist, sich nach einer Sprache umzusehen, die das von Natur
aus kann.

Es ist nicht die Art von Programmierung die C++ gut unterstützt.
Andererseits, welche Sprache bietet eingebaut die Möglichkeit zwischen
verschiedenen Allokationsmechanismen frei und zur Laufzeit(wieso
eigentlich?) zu wählen?

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Georg Maaß
Guest





PostPosted: Sun Dec 14, 2003 6:30 pm    Post subject: Re: virtueller new-Operator geht nicht Reply with quote

Ludwig Pumberger wrote:
Quote:
welche Sprache bietet eingebaut die Möglichkeit zwischen
verschiedenen Allokationsmechanismen frei und zur Laufzeit(wieso
eigentlich?) zu wählen?

Vielleicht gar keine, dann wird das Projekt wegen Unrealisierbarkeit
gestoppt.

--
Georg Maaß - bioshop.de D-76227 Karlsruhe, Westmarkstraße 82
HTML, XML / JavaScript, C++, Java, PHP, VB / CGI, JSP, ASP, ASP.net
- The ultimate DHTML engine: http://gml-modul.sourceforge.net -
http://sourceforge.net/projects/gml-modul

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.