Static Class vs Static Struct vs Namespace

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Static Class vs Static Struct vs Namespace

Beitrag von Glocke » Mi Jan 30, 2013 11:58 am

Hi, ich habe eine prinzipiell Frage: im Quellcode habe ich ein paar (quasi globale) Variablen und Funktionen. Allerdings möchte ich die nicht im globalen Namensraum "rumliegen" haben, sondern mit Foo::value oder Foo::do() aufrufen. Welche der drei folgenden Varianten ist aus eurer Sicht die "beste"?

Variante 1: öffentliche, statische Klassenmember
Eins.hpp

Code: Alles auswählen

class Eins {
    public:
        static int value;
        static int something(int a);
};
Eins.cpp

Code: Alles auswählen

#include "Eins.hpp"

int Eins::value = 0;
int Eins::something(int a) {
    return a * a;
}
Variante 2: statische Strukturmember
Zwei.hpp

Code: Alles auswählen

struct Zwei {
    static int value;
    static int something(int a);
};
Zwei.cpp

Code: Alles auswählen

#include "Zwei.hpp"

int Zwei::value = 0;
int Zwei::something(int a) {
    return a * a;
}
Variante 3: Namespace
Drei.hpp

Code: Alles auswählen

namespace Drei {
    extern int value;
    int something(int a);
}
Drei.cpp

Code: Alles auswählen

#include "Drei.hpp"

int Drei::value = 0;
int Drei::something(int a) {
    return a * a;
}
Aufruf-Beispiel

Code: Alles auswählen

#include <iostream>

#include "Eins.hpp"
#include "Zwei.hpp"
#include "Drei.hpp"

int main() {
    Eins::value += Eins::something(5);
    std::cout << Eins::value << std::endl;
    Zwei::value += Zwei::something(5);
    std::cout << Zwei::value << std::endl;
    Drei::value += Drei::something(5);
    std::cout << Drei::value << std::endl;
}
Vom Aufruf her sind alle 3 Varianten äquivalent. Aber welche sollte ich bevorzugen und warum?

Möchte ich "interne" Daten dazunehmen (die für Außen nicht sichtbar sind), fällt die Namespace-Variante weg, richtig?

LG Glocke :mrgreen:

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Static Class vs Static Struct vs Namespace

Beitrag von Xin » Mi Jan 30, 2013 12:22 pm

Glocke hat geschrieben:Vom Aufruf her sind alle 3 Varianten äquivalent. Aber welche sollte ich bevorzugen und warum?
Ich nehme Klassen, weil...
Glocke hat geschrieben:Möchte ich "interne" Daten dazunehmen (die für Außen nicht sichtbar sind), fällt die Namespace-Variante weg, richtig?
...eben dies.

Ich habe häufig Klassen in der Form

Code: Alles auswählen

class FoobarEnum
{
   int Value;
   char const * StringRepresentation;

   FoobarEnum( int value, char const * stringRepresentation )
     : Value( value ), StringRepresentation( stringRepresentation )
  {}
public:
  static FoobarEnum Snafu, FluppDiWupp;
  const int SnafuValue = 1, 
                   FluppDiWuppValue = 2;

  char const * AsString() const { return StringRepresentation );
  bool operator == ( FoobarEnum & rhs ) const { return Value == rhs.Value; }
};

// foobarenum.cpp

FoobarEnum FoobarEnum::Snafu( FoobarEnum::SnafuValue, "Snafu" );
FoobarEnum FoobarEnum::FluppDiWupp( FoobarEnum::FluppDiWuppValue, "FluppDiWupp" );

int main(void)
{
  FoobarEnum a = FoobarEnum::Snafu;
  FoobarEnum b = FoobarEnum::FluppDiWupp;

  if( a == b ) // schneller Vergleich
    printf( "a und b sind beides %s\n", a.AsString() );
  else
    printf( "a ist %s und b ist %s\n", a.AsString(), b.AsString() );

  switch( a.GetValue() )  // Schnelle Unterscheidung
  {
    case FoobarEnum::SnafuValue: printf( "Snafu!" ); break;
    case FoobarEnum::FluppDiWupp: printf( "FluppDiWupp" ); break;
    default: printf( "?" ); break;
  }
}
Ich nehme keine Structs, weil ich class hier entsprechender finde. Diese Enumklassen tragen häufig auch interessante Informationen, bzw. sind spezielle Marker. Zum Beispiel Angle::RightTurn => 270 Grad, Angle::UTurn => 180 Grad, Angle::LeftTurn => 90 Grad, oder auch Color::Red oder Point::Origin.

Da das alles Klassen sind, ist das Muster eben Klassen zu nehmen.

Mein Compiler hat eine Konfigurationsklasse. Eine Instanz davon ist als statische, globale Variable definiert. Diese eine globale Variable kann ich entsprechend fragen, wie der Compiler konfiguriert ist.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Static Class vs Static Struct vs Namespace

Beitrag von fat-lobyte » Mi Jan 30, 2013 7:09 pm

Statische Funktionen sind kein OK,
aber warum meinst du, dass du unbeding statische variablen brauchst?

Solltest du dein Programm irgendwann mal paralellisieren wollen, dann geht das oft überraschend billig - aber nicht wenn du noch irgendwo etwas statisches hast.
Haters gonna hate, potatoes gonna potate.

Glocke
Beiträge: 332
Registriert: Fr Okt 26, 2012 8:39 am

Re: Static Class vs Static Struct vs Namespace

Beitrag von Glocke » Fr Feb 01, 2013 9:59 am

fat-lobyte hat geschrieben:Statische Funktionen sind kein OK,
aber warum meinst du, dass du unbeding statische variablen brauchst?

Solltest du dein Programm irgendwann mal paralellisieren wollen, dann geht das oft überraschend billig - aber nicht wenn du noch irgendwo etwas statisches hast.
Naja ich habe zum Beispiel alle Sachen die SDL zum Handeln eines Fensters bereitstellt in eine Klasse "Window" reingesteckt und mit Gettern und Setter ("setResolution", getCurrentFps" usw.) versehen. Nun will ich in anderen Teilen des Programms auf das Fenster zugreifen, ohne einen Pointer auf die Instanz mühsam überall hinschleppen zu müssen - der Aufruf "Window::setResolution(800,600)" ist mir da bequemer. Da SDL nur ein Fenster pro Anwendung unterstützt, bin ich auf die Idee der statischen Klasse gekommen. Singleton habe ich nicht in Betracht gezogen, weil ich keinen wirklichen Vorteil dadurch gesehen habe.

Naja und die Namespace-Sache ist wegen der internen Daten (die ich quasi wegkapseln möchte) aus meiner Sicht ungeeignet.

LG Glocke

Antworten