Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Wrapper-Klasse und const-Idee gesucht

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
01.10.2008, 22:46 Uhr
stephanw
localhorst


Hallo,

gegeben ist eine Bibliotheksklasse:

C++:
class Foo
{
public:
  void setValue(int x);
  int getValue() const;
};



Da mir die Schnittstelle nicht gefällt, habe ich eine Wrapper-Klasse:

C++:
class MyFoo
{
  const Foo* object_;
public:
  MyFoo(const Foo* object)
  : object_(object)
  {}
  
  int myGetValue() const
  {
    return object_->getValue();
  }
};



Die Funktion myGetValue() ist kein Problem, denn *object_ ist konstant und dessen Funktion getValue() passt dazu.

Wenn ich aber auch eine Funktion mySetValue(int) in der Wrapper-Klasse anbieten will, habe ich ein Problem: um *object_ ändern zu können, muss ich auf das "const" verzichten:

C++:
class MyFoo
{
  Foo* object_; // nicht const
public:
  MyFoo(Foo* object) // nicht const
  : object_(object)
  {}
  void mySetValue(int v)
  {
    object_->setValue(v);
  }
  ...
};



Das gefällt mir aber nicht, da ich nun keinen Wrapper mehr anlegen kann, wenn ich nur ein "const Foo*" habe, also schon das Originalobjekt nur lesen darf.

Gibt es eine Lösung, die beides unter einen Hut bringt ?

Grüße, Stephan.
--
Reden ist Schweigen und Silber ist Gold.

Dieser Post wurde am 01.10.2008 um 22:52 Uhr von stephanw editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
01.10.2008, 23:37 Uhr
Kest
saint


const weg-casten?: "const_cast<Foo*>(object_)->setValue(x);"

oder so was?:

C++:
class Foo
{
      mutable int wert;
public:
  void setValue(int x) const{ wert=x; }
//...

--
Wenn man einen Hufschlag hört, sollte man >Pferd< denken und nicht >Zebra<.

Dieser Post wurde am 01.10.2008 um 23:59 Uhr von Kest editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
02.10.2008, 00:10 Uhr
ao

(Operator)


Das ist doch ein Widerspruch: Wenn du ein const Foo hast kannst du kein MyFoo drumherum legen, das schreibenden Zugriff erlaubt. Stell dir vor, das Foo liegt in einem ROM und ist physikalisch nicht veränderbar. Wie willst du setValue implementieren, wenn das gar nicht geht?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
02.10.2008, 08:47 Uhr
0xdeadbeef
Gott
(Operator)


So ganz spontan fiele mir dazu folgendes ein:

C++:
class wrapper {
public:
  wrapper(value_t       *p) : rw(p), ro(p) { }
  wrapper(value_t const *p) : rw(0), ro(p) { }

  class access_violation : public std::runtime_error {
    // what() überladen etc.
  };

  int value() const { return ro->GetValue(); }
  void value(int x) throw(access_violation) {
    if(rw) {
      rw->SetValue(x);
    } else {
      throw access_violation();
    }
  }

private:
  value_t       *rw;
  value_t const *ro;
};


...allerdings nimmt das natürlich einen der Hauptvorteile von cv-Qualifiern weg, nämlich die Erkennung von Verletzungen zur Compilezeit.

Wahrscheinlich sinnvoller wäre, fällt mir gerade ein, ein Zwei-Klassen-Ansatz, a la

C++:
class const_wrapper {
public:
  const_wrapper(value_t const *p) : val_(p) { }

  int value() const { return val_->GetValue(); }

private:
  value_t const *val_;
};

class wrapper : public const_wrapper {
public:
  wrapper(value_t *p) : const_wrapper(p), rw_val_(p) { }

  void value(int x) { rw_val_->SetValue(x); }

private:
  value_t *rw_val_;
};


...und dann halt je nachdem, welches Interface du benötigst, const_wrapper oder wrapper akzeptieren.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
02.10.2008, 09:00 Uhr
stephanw
localhorst


Vielen Dank für die Meinungen!

Ein const_cast kommt mir dafür nicht in Frage, schließlich will ich den Sinn dieser Qualifizierer ja gerade hervorheben und nicht umgehen.

@0xdeadbeef:

Ähnliche Konstrukte wie Deine Vorschläge sind mir auch in den Sinn gekommen, auch mit dem von Dir beschriebenen Nachteil des ersten Ansatzes. Die zweite Lösung scheint die beste Wahl zu sein.

Vielleicht gibts ja noch etwas bessere, aber ich glaube, damit könnte ich leben.
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
02.10.2008, 09:28 Uhr
0xdeadbeef
Gott
(Operator)


Ich würde wahrscheinlich Referenzen statt Zeigern benutzen, aber sonst fällt mir dazu eigentlich nicht viel mehr ein.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
02.10.2008, 09:45 Uhr
stephanw
localhorst


Im Prinzip ja, derzeit muss der Wrapper jedoch auch mit Null-Zeigern umgehen können.
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: