Article View: de.comp.lang.c++
Article #1417Re: void* - Felder
From: Dietmar Kuehl
Date: Sat, 27 Jan 1996 21:52
Date: Sat, 27 Jan 1996 21:52
120 lines
4379 bytes
4379 bytes
Hi,
Andrea Hermann (hermann@ipf.bau-verm.uni-karlsruhe.de) wrote:
: ich habe hier ein Programmfragment, von dem ich nicht weiss,
: wieso es nicht tut:
Gehe ich recht der Annahme, das "nicht tut" eigentlich meint "laesst
sich nicht compilieren"? Das koennte ich mir bequem vorstellen:
: int main()
: {
: void* feld;
Ist 'feld' identisch mit 'f'? ... oder ist 'f' ebenfalls als 'void*'
deklariert?
: int typ;
: // typ = 1 fuer int, 2 fuer double,...
: switch( typ )
: {
: case 1: f = ( void* ) new int[n];
Mal ganz davon abgesehen, dass man '(void*)' weglassen kann, da die
Konversion von Pointern nach 'void*' automatisch passiert, deutet die
ganze Sache auf einen (erheblichen) Designfehler hin:
- nicht in eine Klasse eingekapselte built-in Arrays sind fuer mich
bekanntlich sowieso ein rotes Tuch.
- so wie 'f' benutzt wird, ist es viel zu gefaehrlich: Man kann leicht
aus versehen mal den Falschen Cast verwenden und man laeuft in
"undefined behavior".
- wenn ein neuer Typ aufgenommen werden soll, muss in jedem 'switch' ein
entsprechender 'case' aufgenommen werden. Ich vermute, dass hier,
abhaengig von irgendeinem magischen Parameter, ein Vektor von
Objekten eingelesen werden soll. Irgendwann wird man den magischen
Parameter auswerten muessen (der vermutlich eher ein 'enum' anstatt
einem 'int' sein sollte...), da fuehrt vermutlich kein Weg dran
vorbei, aber dannach ist der Typ festgelegt. Was man also machen
koennte, ist in einem 'switch' ein passendes Objekt erzeugen und
das dann fuellen.
: for( int i = 0; i < n; i++ )
: ein >> (int)f[i];
Damit das mit dem 'void*' geht, muss diese Zeile so lauten:
cin >> ((int*)f)[i];
('ein' ist vermutlich ein Typo, oder?)
: break;
: // andere Faelee
: }
: return 0;
: }
: Prinzipiell soll das Teil n Werte aus einer Datei lesen, deren
: Typ in der Variablen typ verschluesselt ist und zur Laufzeit eingelesen
: wird. Aber irgendwie rafft er nicht, dass das jetzt ein int-Feld ist...
Wen wunderts...: In dem Programm versuchst Du 'operator[]()' auf einen
'int' anzuwenden. Aber der ist sicher nicht definiert (der Standard
definiert ihn nicht und der Benutzer kann ich nicht definieren, da
Operatoren fuer built-in Typen nicht ueberladen werden koennen). Hier
ist uebrigens mein Vorschlag:
// #include <iostream> nach Standard...
#include <iostream.h>
#include <vector>
#include <cstring>
template <class T> void read_vector(istream &in, vector<T> &vec, int dim)
{
for (int i = 0; i < dim; i++)
in >> vec[i]; // sollte eigentlich auch gechecked werden...
}
int main(int ac, char *av[])
{
if (ac < 2)
{
cerr << "Usage: " << av[0] << " <type>\n";
return 1;
}
int dimension = 3;
if (!strcmp(av[1], "int"))
{
vector<int> vec(dimension);
read_vector(cin, vec, dimension);
//...
}
else if (!strcmp(av[1], "double"))
{
vector<double> vec(dimension);
read_vector(cin, vec, dimension);
//...
}
// else if ...
return 0;
}
Das laesst sich mit gcc-2.7.2 und libg++-2.7.1 compilieren. Leider
funktioniert 'string' nicht so wie es soll, sonst koennte man z.B.
'string(av[1]) == "int"' anstell von dem 'strcmp()' Kram schreiben.
Wenn man die verschiedenen Vektoren in dem selben Code verwendet werden
sollen, dann kann man sich eine abstrakte Basisklasse mit den noetigen
Eigenschaften definieren, von der man dann ein passendes Template
ableitet. Das kann man dann (typsicher) verwenden, ohne jemals wieder
einen 'switch' zu benoetigen.
--
dietmar.kuehl@uni-konstanz.de
http://www.informatik.uni-konstanz.de/~kuehl
I am a realistic optimist - that's why I appear to be slightly pessimistic
Technical Details
Message-ID:
<310a9ea2.0@news.uni-konstanz.de>Path:
arc1-ca.pugleaf.net!news.uni-stuttgart.de!horn!kuehlReferences:
<3109142F.41C67EA6@ipf.bau-verm.uni-karlsruhe.de>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!news.uni-stuttgart.de!horn!kuehl From: kuehl@horn.informatik.uni-konstanz.de (Dietmar Kuehl) Newsgroups: de.comp.lang.c++ Subject: Re: void* - Felder Date: 27 Jan 96 21:52:34 GMT Organization: Fakultät für Mathematik und Informatik Message-ID: <310a9ea2.0@news.uni-konstanz.de> References: <3109142F.41C67EA6@ipf.bau-verm.uni-karlsruhe.de> Reply-To: dietmar.kuehl@uni-konstanz.de NNTP-Posting-Host: minerva.rz.uni-konstanz.de X-Newsreader: TIN [version 1.2 PL2]