🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: de.comp.lang.c++
Article #1417

Re: void* - Felder

#1417
From: Dietmar Kuehl
Date: Sat, 27 Jan 1996 21:52
120 lines
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!kuehl
References: <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]