Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

11

23.10.2015, 15:47

@BilderbergerK
Warum denkst du, dass der Ansatz nicht flexibel genug ist? Was genau möchtest du den erreichen und was funktioniert mit diesem Ansatz nicht? Prinzipiell sollte der Ansatz mindestens das erlauben, wonach dem du gefragt hattest. Deinen Code verstehe ich übrigens nicht. Von privater Ableitung würde ich auch abraten.

@BlueCobold
Die Anmerkung ist ja mal total am Thema vorbei. Mir scheint, du diskutierst gerne.
Und nein, das ist nicht unsinnig. Es gibt es im Wesentlichen zwei verschiedene Arten von Größen: Zahlen zur Dimensionierung von Speicher und Zahlen die eine andere freie Semantik und Wertebereich besitzen und unabhänig von Speicher sind (Eine Zeit in Sekunden wäre ein Beispiel). int in der Sprache von C(++) besitzt leider weder die eine noch die andere Semantik und ist somit prinzipiell weder für das eine noch für das andere geeignet. int ist ein Phänomen der Vergangenheit, als es noch viele Architekturen gab, die nicht auf Bytes basierten. Deshalb wurden damals im Standard die eingebauten Typen nicht auf feste Größe festgelegt. Heute allerdings ist es in plattformunabhänigen Code höchstens störend, das normale Integertypen ihren Wertebereich zwischen Architekturen und Compilern ändern können und das auch tun. Das Paradebeispiel ist wohl der Unterschied bei long zwischen Linux und Windows. Die Menge an sinnlosen Ärger den das schon bedeutet hat, ist gigantisch und eigentlich nicht zu rechtfertigen. Besonders die Tendenz vieler Linux-Programmierer zur Annahme, dass ihre C(++) Typen überall gleich wären und doch sicher überall das LP64 Model gelten würde, führt bei Portierungen häufig zu Problemen im Wertebereich. "Einfache" Probleme mit eigentlich überflüssigen Casts treten noch häufiger auf, wenn die eingebauten Typen verwendet werden.

Viele moderne verwandte Sprachen für moderne Plattformen verhindern das Problem heutzutage auch korrekt. Dazu gehören zum Beispiel C#, Java, Rust oder D. All die Sprachen machen es richtig. Das macht deutlich, dass die Vorteile von Integer Typen fester Größe für die meisten Fälle überwiegen und heutzutage die richtige Wahl sind.

Wenn man sich auf eine Menge von Plattformen und Compiler beschränkt, kann man mit genauen Festlegungen theoretisch auch mit den eingebauten Typen auskommen. Das ist meiner Meinung etwas engsichtig. Der einzige Grund gegen die Verwendung von Typen fester Größe ist doch, um mit alten Code konsistent zu bleiben und Tippfaulheit. Das kann ich auch verstehen, allerdings nicht warum man ihre Verwendung so schlecht finden könnte.
Hallo Spiele-Programmierer,

vielleicht kenne ich mich noch nicht so gut mit Template-Programmierung aus,
allerdings habe ich es oft so, dass ich in einer Basisklasse ein statisches Attribut habe auf den ein paar Grundklassen basieren. - Wenn ich nun eine neue Klasse bilde, die auf mehreren Grundklassen abgeleitet ist dann tritt der Fehler auf, dass das statische Attribute schon vorhanden sei.

Noch als Anmerkung _int32 kann Vor- und Nachteile haben.


Gruß

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

12

23.10.2015, 15:55

@BlueCobold
Totaler Unsinn. Ich habe plattform-unabhängigen Code, der läuft fehlerfrei auf 5 Systemen. Nirgends ist da ein int_32t. Ist auch gar nicht notwendig. Ich wüsste auch nicht wofür. Der Wertebereich ist durch Deinen Anwendungsfall beschränkt und nicht davon abhängig, ob das hier mal 32 Bit hat und dort 64 oder nicht. Es ist überhaupt in keiner Weise irgendwie störend, wie groß der int denn wirklich ist. Ich wüsste auch nicht warum. Im besten Fall ist der int größer als die 32 Bit, die Du mit int_32t festschreibst. Weniger wird es so ziemlich nirgendwo sein, auch wenn das rein theoretisch möglich wäre mit irgendeinem isoterischen Compiler. Was Du da beschreibst, ist praktisch irrelevanter Unfug. Das ist genau wie die Behauptung man solle char, short und int benutzen, je nachdem was für Werte man hat (z.B. char für Alter, weil das ja nie auch nur bis 110 geht). Im Normalfall hat der Compiler ohne die Festschreibung die besseren Optionen. Lass ihn machen, er weiß es besser als Du.

allerdings habe ich es oft so, dass ich in einer Basisklasse ein statisches Attribut habe auf den ein paar Grundklassen basieren.
Das klingt nach einem ganz ganz argen Design-Fehler. Wozu glaubst Du das zu brauchen und auch noch vererben zu müssen? Klingt doch für mich eher so als ob Du da eigentlich eine virtuelle Methode willst, die eine ID liefert und keine statische Property.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (23.10.2015, 16:09)


13

23.10.2015, 16:19

@BlueCobold
Totaler Unsinn. Ich habe plattform-unabhängigen Code, der läuft fehlerfrei auf 5 Systemen. Nirgends ist da ein int_32t. Ist auch gar nicht notwendig. Ich wüsste auch nicht wofür. Der Wertebereich ist durch Deinen Anwendungsfall beschränkt und nicht davon abhängig, ob das hier mal 32 Bit hat und dort 64 oder nicht. Es ist überhaupt in keiner Weise irgendwie störend, wie groß der int denn wirklich ist. Ich wüsste auch nicht warum. Im besten Fall ist der int größer als die 32 Bit, die Du mit int_32t festschreibst. Weniger wird es so ziemlich nirgendwo sein, auch wenn das rein theoretisch möglich wäre mit irgendeinem isoterischen Compiler. Was Du da beschreibst, ist praktisch irrelevanter Unfug. Das ist genau wie die Behauptung man solle char, short und int benutzen, je nachdem was für Werte man hat (z.B. char für Alter, weil das ja nie auch nur bis 110 geht). Im Normalfall hat der Compiler ohne die Festschreibung die besseren Optionen. Lass ihn machen, er weiß es besser als Du.

allerdings habe ich es oft so, dass ich in einer Basisklasse ein statisches Attribut habe auf den ein paar Grundklassen basieren.
Das klingt nach einem ganz ganz argen Design-Fehler. Wozu glaubst Du das zu brauchen und auch noch vererben zu müssen? Klingt doch für mich eher so als ob Du da eigentlich eine virtuelle Methode willst, die eine ID liefert und keine statische Property.
Ja?

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Index
{
int index=0;
};

class A : public Index
{
        A()
        {
        index++;
        }
};



class B : public Index
{
        B()
        {
        index++;
        }
};


print("A: %i; B%i\n", A::index, B::index);

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

14

23.10.2015, 16:24

@BilderbergerK
Warum hast du verschiedene Variablen mit gleichen Namen? Warum benennst du die Variablen in der Basisklasse nicht einfach unterschiedlich? In deinem Beispiel sehe ich auch kein Problem, weil es nur eine Variable gibt und diese als auch die Vererbung privat sind.

Falls es mehrere Variablen mit gleichen Namen gibt, so gewinnt ohne der Angabe des Klassennamens immer die in der Klassenhierarchie letzte deklaration. Bei Mehrfachvererbungen kannst du mit using auswählen, welche Basisklasse den Vorang hat.

Ich verstehe allerdings momentan überhaupt nicht wofür du das brauchst. Ich würde mal vorschlagen, dass du mal genauer beschreibst was du gerade erreichen möchtest.

@BlueCobold
Na dann sei glücklich. Ich habe da bereits genau die Gegenteilige Erfahrung gemacht. In der Praxis ist momentan besonders der long-Typ problematisch. int kann man theoretisch verwenden, aber dann kommen bloß unnötige Casts weil das nirgends zusammenpasst. In der reallen Welt sind die meisten Typen auf Speicher bezogen (zum Beispiel STL Container) oder auf feste Typen in Dateien oder Protokollen.

Die zweite Sache die du ansprichst hat damit eher weniger zu tun.

EDIT:
Dein neues Beispiel wirkt nochmal seltsamer. Wofür das Ganze?

15

23.10.2015, 16:40

@BlueCobold
Totaler Unsinn. Ich habe plattform-unabhängigen Code, der läuft fehlerfrei auf 5 Systemen. Nirgends ist da ein int_32t. Ist auch gar nicht notwendig. Ich wüsste auch nicht wofür. Der Wertebereich ist durch Deinen Anwendungsfall beschränkt und nicht davon abhängig, ob das hier mal 32 Bit hat und dort 64 oder nicht. Es ist überhaupt in keiner Weise irgendwie störend, wie groß der int denn wirklich ist. Ich wüsste auch nicht warum. Im besten Fall ist der int größer als die 32 Bit, die Du mit int_32t festschreibst. Weniger wird es so ziemlich nirgendwo sein, auch wenn das rein theoretisch möglich wäre mit irgendeinem isoterischen Compiler. Was Du da beschreibst, ist praktisch irrelevanter Unfug. Das ist genau wie die Behauptung man solle char, short und int benutzen, je nachdem was für Werte man hat (z.B. char für Alter, weil das ja nie auch nur bis 110 geht). Im Normalfall hat der Compiler ohne die Festschreibung die besseren Optionen. Lass ihn machen, er weiß es besser als Du.

allerdings habe ich es oft so, dass ich in einer Basisklasse ein statisches Attribut habe auf den ein paar Grundklassen basieren.
Das klingt nach einem ganz ganz argen Design-Fehler. Wozu glaubst Du das zu brauchen und auch noch vererben zu müssen? Klingt doch für mich eher so als ob Du da eigentlich eine virtuelle Methode willst, die eine ID liefert und keine statische Property.

@BilderbergerK
Warum hast du verschiedene Variablen mit gleichen Namen? Warum benennst du die Variablen in der Basisklasse nicht einfach unterschiedlich? In deinem Beispiel sehe ich auch kein Problem, weil es nur eine Variable gibt und diese als auch die Vererbung privat sind.

Falls es mehrere Variablen mit gleichen Namen gibt, so gewinnt ohne der Angabe des Klassennamens immer die in der Klassenhierarchie letzte deklaration. Bei Mehrfachvererbungen kannst du mit using auswählen, welche Basisklasse den Vorang hat.

Ich verstehe allerdings momentan überhaupt nicht wofür du das brauchst. Ich würde mal vorschlagen, dass du mal genauer beschreibst was du gerade erreichen möchtest.

@BlueCobold
Na dann sei glücklich. Ich habe da bereits genau die Gegenteilige Erfahrung gemacht. In der Praxis ist momentan besonders der long-Typ problematisch. int kann man theoretisch verwenden, aber dann kommen bloß unnötige Casts weil das nirgends zusammenpasst. In der reallen Welt sind die meisten Typen auf Speicher bezogen (zum Beispiel STL Container) oder auf feste Typen in Dateien oder Protokollen.

Die zweite Sache die du ansprichst hat damit eher weniger zu tun.

EDIT:
Dein neues Beispiel wirkt nochmal seltsamer. Wofür das Ganze?



Z.B. will ich den Index eines Jeden Objektes aufrufen koennen, ohne das
Attribut neu zu definieren oder mit unterschiedlichen Namen.

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

16

23.10.2015, 16:45


dein Lösungsansatz ist nicht schlecht, allerdings nicht flexibel genug.
Wofür man so etwas braucht? - Wenn man mehrmals von einer Klasse vererbt, die einen statischen Attribut hat.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Basis
{
static int BaseID=0;
};

class A : private Basis
{
...
};


class B : private Basis
{...};

class SuperKlasse : public A, public B  //A und B brauchen jeweils den statischen Member BaseID
{
....
};



Du koenntest etwas dergleichen machen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template<typename T> class Basis
{
static int BaseID=0;
};

class A : private Basis<A>
{
...
};


class B : private Basis<B>
{...};

class SuperKlasse : public A, public B  //A und B brauchen jeweils den statischen Member BaseID
{
  void test() {
     std::cout << Basis<A>::BaseID << Basis<B>::BaseID << std::endl;
  }
};

Das ist jedoch eine ziemlich unelegante Loesung wuerde ich sagen. Ich wuerde bei deinem Designproblem ein paar Schritte zurueck machen und nach alternativen Loesungen suchen, ich glaube nicht, dass dies ein guter Weg ist. Eventuell moechtest du das groessere Designproblem mal beschreiben.

17

24.10.2015, 03:26

Komisch,

nachdem ich das Problem rekonstruieren wollte kann der Code compiliert werden.
Ich melde mich noch einmal wenn der Fehler wieder auftritt.

Danke an alle.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

18

24.10.2015, 09:41

Es gibt es im Wesentlichen zwei verschiedene Arten von Größen: Zahlen zur Dimensionierung von Speicher und Zahlen die eine andere freie Semantik und Wertebereich besitzen und unabhänig von Speicher sind (Eine Zeit in Sekunden wäre ein Beispiel). int in der Sprache von C(++) besitzt leider weder die eine noch die andere Semantik und ist somit prinzipiell weder für das eine noch für das andere geeignet. int ist ein Phänomen der Vergangenheit, als es noch viele Architekturen gab, die nicht auf Bytes basierten. Deshalb wurden damals im Standard die eingebauten Typen nicht auf feste Größe festgelegt. Heute allerdings ist es in plattformunabhänigen Code höchstens störend, das normale Integertypen ihren Wertebereich zwischen Architekturen und Compilern ändern können und das auch tun. Das Paradebeispiel ist wohl der Unterschied bei long zwischen Linux und Windows. Die Menge an sinnlosen Ärger den das schon bedeutet hat, ist gigantisch und eigentlich nicht zu rechtfertigen. Besonders die Tendenz vieler Linux-Programmierer zur Annahme, dass ihre C(++) Typen überall gleich wären und doch sicher überall das LP64 Model gelten würde, führt bei Portierungen häufig zu Problemen im Wertebereich. "Einfache" Probleme mit eigentlich überflüssigen Casts treten noch häufiger auf, wenn die eingebauten Typen verwendet werden.

Sorry, aber was du da schreibst ist völliger Unsinn. Portabilität ist überhaupt erst der Grund wieso int gerade keine feste Größe hat; mit der Anzahl der Bits in einem Byte hat das überhaupt nichts zu tun und erst recht ist es kein "Phänomen der Vergangenheit". int hat sowohl in C als auch in C++ eine ganz klar definierte Semantik und auch einen klar definierten Wertebereich. Jegliche Menge an "Ärger" und Problemen die diesbezüglich irgendwo entstehen mag, ist ausschließlich auf mangelndes Verständnis seitens der beteiligten Programmierer zurückzuführen.

Viele moderne verwandte Sprachen für moderne Plattformen verhindern das Problem heutzutage auch korrekt. Dazu gehören zum Beispiel C#, Java, Rust oder D. All die Sprachen machen es richtig. Das macht deutlich, dass die Vorteile von Integer Typen fester Größe für die meisten Fälle überwiegen und heutzutage die richtige Wahl sind.

https://de.wikipedia.org/wiki/Zirkelschluss ;)

Ich habe da bereits genau die Gegenteilige Erfahrung gemacht. In der Praxis ist momentan besonders der long-Typ problematisch. int kann man theoretisch verwenden, aber dann kommen bloß unnötige Casts weil das nirgends zusammenpasst. In der reallen Welt sind die meisten Typen auf Speicher bezogen (zum Beispiel STL Container) oder auf feste Typen in Dateien oder Protokollen.

Inwiefern der "long-Typ" "in der Praxis problematisch" sein soll entzieht sich gerade meiner Vorstellungskraft, aber ich kann dir mit Sicherheit sagen, dass, wenn die Präsenz von int dich in deinem Code zu "unnötigen Casts" zwingt, weil "nirgendwo was zusammenpasst", mit deinem Code was nicht ganz in Ordnung sein kann...

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »dot« (24.10.2015, 09:53)


Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

19

24.10.2015, 11:13

Zitat

Portabilität ist überhaupt erst der Grund wieso int gerade keine feste Größe hat;

Es war der Grund. Heutzutage gibt es praktisch keine Architektur mehr, die damit Schwierigkeiten hätte.
Sehr wohl gibt es aber unterschiedliche Ansichten auf der selben Architektur, woran die Größe der Typen bemessen werden kann.

Zitat von »dot«

erst recht ist es kein "Phänomen der Vergangenheit".

Dann nenn mir mal wenigstens eine aktuelle Architektur für die das nicht zutrifft.

Zitat von »dot«

int hat sowohl in C als auch in C++ eine ganz klar definierte Semantik und auch einen klar definierten Wertebereich.

Nö hat er nicht. Der C99-Standard und damit auch der C++11 Standard schreibt wortwörtlich nur folgende Dinge über den Wertebereich:
"minimum value for an object of type int INT_MIN -32767 // −(2 15 − 1)"
"maximum value for an object of type int INT_MAX +32767 // 2 15 − 1"
"A ‘‘plain’’ int object has the natural size suggested by the architecture of the execution environment"
"For any two integer types with the same signedness and different integer conversion rank, the range of values of the type with smaller integer conversion rank is a subrange of the values of the other type"
Ein int soll also mindestens so groß sein wie ein short oder ein signed char und der Größe entsprechen, die die Architektur vorschlägt. Diese Aussage ist extrem vage und lässt viel Interpretationsspielraum für Entscheidungen nach Bedarf, Lust und Laune (Siehe Datenmodell). Insbesondere sind 32 Bit inzwischen eigentlich gar nicht mehr die native Größe der x64 Architektur.
Man könnte jetzt natürlich behaupten, dass die Typen trotzdem eine Semantik besitzen. Diese beschränkt sich aber auf sehr vage Formulierungen und deckt sich mit kaum einen Bedarf der Praxis. Ich wüsste beim besten Willen nicht in welchen Zusammenhang jemand einen Typ (int) brauchen könnte, der auf 32 Bit MSDOS 16 Bit groß ist und auf 32 Bit NT Windows 32 Bit. Oder ein Typ (long) der auf 64 Bit Windows 32 Bit groß ist und auf 64 Bit Linux 64 Bit. Das ist doch Schwachsinn.

Zitat von »dot«

https://de.wikipedia.org/wiki/Zirkelschluss ;)

:?: Ich denke nicht das das hier zutrifft. Unter den modernen Sprachen werden durch die Bank Typen fester Größe verwendet. Diese Entscheidung kommt ja nicht von irgendwoher. Das ist ein Zeichen dafür, dass heutzutage die Vorteile fester Typen für die meisten Entwickler wohl eigentlich überliegen würden. Das ist außerdem ein Beispiel und kein Beweis.

Zitat von »dot«

Inwiefern der "long-Typ" "in der Praxis problematisch" sein soll entzieht sich gerade meiner Vorstellungskraft, aber ich kann dir mit Sicherheit sagen, dass, wenn die Präsenz von int dich in deinem Code zu "unnötigen Casts" zwingt, weil "nirgendwo was zusammenpasst", mit deinem Code was nicht ganz in Ordnung sein kann...

Du willst mir also sagen, dass du noch nie mit einer Bibliothek zu tun hattest, die falsche Annahmen zu long gemacht hat und ihn als 64 Bit angenommen hat? Das kann ich mir irgendwie nicht vorstellen. Sogar der C-Standard selbst ist betroffen, indem zum Beispiel die C-Dateifunktionen wie ftell auf Windows nicht mit großen Dateien auskommen. Auf Windows muss man dann die Extension _ftelli64 verwenden. Soetwas finde ich ganz große Klasse. Diese Probleme haben ihren Ursprung in den falschen Annahmen über die Größe von Typen. Hätte man nicht einen eingebauten Typen verwendet sondern einen Typedef für den entsprechenden Bedarf, hätte es nie ein Problem gegeben. Die eingebauten Typen decken sich nunmal sehr selten mit dem Bedarf der Realität.

Zitat von »dot«

wenn die Präsenz von int dich in deinem Code zu "unnötigen Casts" zwingt, weil "nirgendwo was zusammenpasst", mit deinem Code was nicht ganz in Ordnung sein kann...

Bei der Verwendung im Zusammenhang mit Speicher als Indices oder Größenangaben, gibt es andauerend Casts in size_t oder ptrdiff_t. Außerdem entstehen sie an allen Stellen, an dem Kontakt zur Außenwelt aufgenommen wird. Serialisierung oder WinAPI seien mal als Beispiele genannt.

Ich wüsste nicht wie solche Casts vermieden werden sollen. Die Ursache liegt einfach darin, dass ein Typ verwendet wird, der nicht dem tatsächlichen Bedarf entspricht.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

20

24.10.2015, 11:24

size_t ist unsigned. Klar ist das nicht zu int kompatibel. Aber auch nicht zu int_32t. :whistling: size_t entspricht sogar ganz prima dem Bedarf von Indices in einem Container oder einer Länge von Strings, denn die können einfach mal nicht negativ sein.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige