|
You last visited: Today at 11:36
Advertisement
Objekte[n] von einer Klasse erstellen
Discussion on Objekte[n] von einer Klasse erstellen within the C/C++ forum part of the Coders Den category.
08/20/2012, 23:33
|
#16
|
elite*gold: 0
Join Date: Jul 2012
Posts: 56
Received Thanks: 5
|
Aber meins wäre auch richtig oder? Laut dem Anfang deines Beitrags ,,Er könnte auch so aussehen:,, schließe ich nun ab, dass meine Form ebenfalls richtig ist.. Ich bin etwas schreibfaul um ehrlich zu sein umso kürzer umso besser^^
Das mit der using-Direktive und namespace muss ich mir mal später nochmal durchlesen.
Konstruktoren und Dekonstruktoren werde ich gleich mal beginnen sobald meine Serie hier zu Ende ist.
Vielen Dank aufjedenfall an alle die mich hier etwas hinbiegen wollen.
Soll ich #pragma once nur benutzen, wenn ich an der Stelle auch #ifndef/#define gemacht hätte?
Im Internet habe ich grad keinen Nachteil darüber gelesen, außer dass einige Compiler #pragma once nicht unterstützen.
|
|
|
08/20/2012, 23:36
|
#17
|
elite*gold: 0
Join Date: May 2011
Posts: 30
Received Thanks: 7
|
Also deine Form wird nicht aufgehen, sorry wenn ich mich etwas missverständlich ausgedrückt habe.
Code:
Konto::Konto(double 0.00/*Geht nicht weil du keine Zahl als Variablenname nutzen kannst*/)
Konto::Konto(/* Für den Anfangswert des Kontostands */)
{
double kontostand = 0.00 //Sofern du "kontostand" schon als Klasseninterne Variable hast würdest du sie doppelt definieren, einfach das "double" weglassen du kannst ja aus den Methoden auf Member zugreifen
}
|
|
|
08/21/2012, 18:36
|
#18
|
elite*gold: 5
Join Date: Sep 2006
Posts: 385
Received Thanks: 218
|
Quote:
Originally Posted by Hg(CNO)2
Aber meins wäre auch richtig oder? Laut dem Anfang deines Beitrags ,,Er könnte auch so aussehen:,, schließe ich nun ab, dass meine Form ebenfalls richtig ist.. Ich bin etwas schreibfaul um ehrlich zu sein umso kürzer umso besser^^
|
Code:
Konto::Konto(double 0.00/* Für den Anfangswert des Kontostands */)
// oder
Konto::Konto(/* Für den Anfangswert des Kontostands */)
{
double kontostand = 0.00}
double 0.00 -> Wie legt man Variablen an (was anderes sind Parameter nicht)? Datentyp Wert? Wäre mir neu. Schau nochmal im Kapitel Grundlagen nach, da sollte das i.d.R. stehen (das ist nichts schlimmes, dafür hast du das Buch ja schließlich).
double kontostand = 0.00 -> Womit müssen Anweisungen beendet werden? 
Außerdem; wenn du das so machst, dann ist die Variable kontostand lediglich im Konstruktor vorhanden. Sobald dieser verlassen wird, dann gibt es sie nicht mehr.
Kurzes Beispiel:
Code:
void foo()
{
//Die Variable lebt von hier:
int bar = 0;
} //bis hier
//hier gibt es bar nicht mehr
Willst du also, dass kontostand so lange lebt, wie deine Klasse, dann musst du die Variable in der Klasse angeben.
Code:
class Foo
{
private:
int mBar;
public:
Foo();
~Foo();
};
Foo::Foo() :
mBar(0) //Wenn du mBar nicht initialisierst, dann kann alles mögliche in der Variable stehen
{
}
Foo::~Foo()
{
}
int main()
{
{ //Nur zur Demonstration, der Scope hat hier keinen Nutzen
Foo foo; //mBar wurde mit der Klasse erstellt
} //hier stirbt mBar mit foo
//Hier gibt es foo und somit mBar nicht mehr
}
Quote:
Originally Posted by Hg(CNO)2
Soll ich #pragma once nur benutzen, wenn ich an der Stelle auch #ifndef/#define gemacht hätte?
Im Internet habe ich grad keinen Nachteil darüber gelesen, außer dass einige Compiler #pragma once nicht unterstützen.
|
Ich kenne keinen (aktuellen) mainstream Compiler, der das nicht unterstützt. Und es ist (minimal) schneller, da #pragma once eine im Compiler fest verbaute Funktion ist. Das geht nicht den Umweg über if/else.
Ist auch nicht wirklich wichtig der Punkt, mehr so eine persönliche Präferenz.
|
|
|
08/22/2012, 12:38
|
#19
|
elite*gold: 0
Join Date: Jul 2012
Posts: 56
Received Thanks: 5
|
Wann soll ich ein Konstruktor und wann eine Methode für meine erstellten Objekte verwenden? Also bei welchem Sachbestand eignet sich eine Methode...
Den Unterschied den ich dabei bemerke ist der Rückgabetyp. Der existiert bei Konstruktoren gar nicht. Also jedes Mal wenn ich mit Rückgabetypen arbeiten möchte?
Ist es irrelevant, ob man structs, unions oder class für die Klassen Definition verwendet? Abgesehen von den Voreinstellungen der jeweiligen Definitionsarten.
Wenn ich nun ein Objekt erstellt habe soll der Nutzer seinen Namen eingeben und dieser Name soll im Objekt auf ein Datenelement angelegt werden. Was soll ich da am Besten benutzen ein Konstruktor oder eine Methode?
Code:
bool init_kunde(std::string&); // Methode
// oder
Konto(std::string&); // Konstruktor
Mir kam gerade diese Idee:
Code:
Konto::Konto(std::string& name)
{
if(name.size() <= 4)
{
std::cout << "Der eingegebene Name ist ungueltig oder zu klein";
}
}
Ist das Sinnvoll oder mal wieder von mir willkürlich kreirrt?
|
|
|
08/22/2012, 13:16
|
#20
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
Prinzipiell ist immer der Konstruktor vorzuziehen.
Was die create Methode mit Rückgabetyp angeht, gibt es da zwei Ansichten:
1. Wenn es fehlschalgen kann, gehört es nicht in den Konstruktor. Dann gehört es in eine init/create Methode, die einen Rückgabewert hat oder anders Fehlerinformationen liefert (zb. Exceptions)
2. Du kannst aus einem Konstruktor genau wie aus jeder Funktion eine Exception werfen, die einen Fehlerfall anzeigt. Wenn du vorher schon Heap Speicher alloziert hast, musst du den natürlich wieder freigeben, wenn du so eine Exception fängst.
Das entspricht dem RAII (Resource Aquisition is Initialisation) Prinzip.
Wie gesagt, in C++ sollte man eher zu 2. tendieren, denn dafür gibt es die Sprachmittel.
Wer aus der C Welt kommt, wird eher an init Methoden gewöhnt sein, da RAII so in C nicht vorkommt und Klassen die meisten sowieso schon genug überfordern  Java Programmierer kommen damit noch klar (init Methoden gibt es da eher selten), dafür sieht es da anders mit Destruktoren aus, die es dort einfach nicht gibt (ein Java Programmierer muss seine Resourcen also immer explizit freigeben und kann sie nicht automatisch im Destruktor freigeben lassen).
Kommt halt auch immer drauf an, ob du Exceptions oder einen Rückgabewert haben willst. Immer dann, wenn Exceptions eher ungeeignet wären (und solche Fälle gibt es), macht es mehr Sinn eine init Methode mit entsprechendem Rückgabetyp zu erstellen.
Wenn du sowieso mit Exceptions arbeitest, ist es im Grunde genommen wurscht, dann kommt es einfach auf dein Design an (soll das Objekt sofort mit der Erstellung auch initiailisiert sein oder soll es erstmal ein "Zombie-Objekt" sein und wirklich erst dann sinnvolle Daten enthalten, wenn du es explizit angibst?).
Quote:
|
Ist es irrelevant, ob man structs, unions oder class für die Klassen Definition verwendet? Abgesehen von den Voreinstellungen der jeweiligen Definitionsarten.
|
class und struct sind im Grunde das gleiche.
Eine Klasse hat standardmäßig alle Mitglieder (Methoden und Datenelemente) auf private und public Zugriff muss explizit angegeben werden. Bei einer Struktur ist es genau umgekehrt.
Strukturen werden i.d.R. nur für reine Datenansammlungen, die man unter einem Namen zusammenfassen will, verwendet, während man komplexere Designs mit Methoden, Polymorphie etc. eigentlich nur für Klassen verwendet, obwohl es auch bei Strukturen möglich wäre.
Eine union ist veraltet und meines Wissens wird davon abgeraten, sie noch zu verwenden.
Soweit ich weiß, fasst sie ein und dieselben Daten unter verschiedenen Namen zusammen:
Code:
union FloatOderInt
{
int x;
float y;
};
FloatOderInt var;
var.x = 5;
var.y = 5.0f;
x und y greifen auf dieselben Daten zu, nur werden sie einmal als Int und einmal als Float interpretiert.
Wie gesagt, normalerweise lassen sie sich vermeiden und werden deshalb auch nur selten verwendet.
Es kann aber praktisch sein, ein und dieselbe Variable unter verschiedenen Namen anzusprechen (wobei meines Erachtens dann einfach das Design Schrott ist), wie es in der Windows API gerne mal passiert.
Sie sind eingeschränkte Klassen, können also auch Methoden, Konstruktoren etc. haben, können aber werder von anderen Klassen erben noch vererben und dementsprechend auch nicht polymorph sein.
Sie haben wie Strukturen einen Standard-Public-Zugriff.
|
|
|
08/22/2012, 13:58
|
#21
|
elite*gold: 0
Join Date: Jul 2012
Posts: 56
Received Thanks: 5
|
Ich kenne mich mit diesen Exceptions nicht genau aus hab ab und zu mal was im Buch darüber gehört, dass es für Fehlsituationen angewendet wird und in einigen Quelltexten mal catch, throw etc. gelesen aber habe mich halt noch nicht damit befasst.
Mit dem Satz:
Quote:
|
2. Du kannst aus einem Konstruktor genau wie aus jeder Funktion eine Exception werfen, die einen Fehlerfall anzeigt. Wenn du vorher schon Heap Speicher alloziert hast, musst du den natürlich wieder freigeben, wenn du so eine Exception fängst.
|
Die Freigabe des Speichers einer Exception wird dann durch Destruktoren freigegeben oder durch bestimmte Schlüsselwörter von Exception-Handlings? Ich kenn mich mit Exception-Handling nicht aus aber ich denke das wird in weiteren Kapiteln dementsprechend behandelt ansonsten lese ich es mal nach dem Kapitel "Konstruktor/Destruktor" durch, wenn es dazu gehören sollte.
Edit// Ich erstelle mal eine Exception in meinem Konstruktor falls eben der Anwender irgendwas falsch eingegeben/reagiert hat. Soll der Speicher der Exception wieder freigegeben werden. Geschieht das dann durch einen Destruktor oder von selbst/mit einem Schlüsselwort?
|
|
|
08/22/2012, 14:22
|
#22
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
Die Freigabe von Exceptions meinte ich damit nicht.
Zerbrich dir darüber einfach nicht den Kopf, wenn du da noch nicht bist.
|
|
|
08/22/2012, 17:28
|
#23
|
elite*gold: 5
Join Date: Sep 2006
Posts: 385
Received Thanks: 218
|
Quote:
Originally Posted by MrSm!th
(wobei meines Erachtens dann einfach das Design Schrott ist)
|
Das kann ich so nicht stehen lassen. unions haben, wie jedes andere Mittel der Sprache, einen Grund, warum sie existieren. Und nur weil du ihn (noch) nicht kennst oder falsch kennen gelernt hast, heißt das nicht, dass das "Schrott" ist.
Beispiel:
Code:
typedef unsigned char byte;
union word
{
struct
{
byte low, high;
};
unsigned short value;
};
union dword
{
struct
{
word low, high;
};
unsigned long value;
};
union qword
{
struct
{
dword low, high;
};
unsigned long long value;
};
union color
{
struct
{
byte b, g, r, a;
};
unsigned long value;
};
int main()
{
qword someQword;
someQword.value = 0xAABBCCDDEEFF0011;
dword high = someQword.high, //0xAABBCCDD
low = someQword.low; //0xEEFF0011
word lower = low.low; //0x0011
byte theLowest = lower.low; //0x11
color someColor;
someColor.value = 0xFFB000B5;
//someColor.a => 0xFF
//someColor.r => 0xB0
//someColor.g => 0x00
//someColor.b => 0xB5
}
Ist das nicht schöner, lesbarer und verständlicher als Bitschieberei? Das ist so ziemlich das Gegenteil von schlechtem Design.
|
|
|
08/22/2012, 17:58
|
#24
|
elite*gold: 0
Join Date: Jul 2012
Posts: 56
Received Thanks: 5
|
Wenn ich geschwind zwischen euch beiden Funken dürfte.
Vorwort: Ich habe jetzt direkt und ohne große Gedanken das Ganze neu programmiert. Hin und wieder könnte euch etwas auffallen, wo ich Fehler wiederhole, überflüssiges Zeug programmiert habe.
Was euch auch stört und zu bemängeln habt, sagt bescheid.
Momentan habe ich folgendes Problem:
Der Nutzer dieses Programms (i.d.R. der Kontoinhaber) soll am Anfang in der Hauptfunktion angeben, was er tun möchte.
Menüfunktionen werden durch Integer-Zahlen erkannt alles am Source erkennbar.
Ich möchte nun, wenn der Kunde sein Kontostand bzw. Kontoübersicht auswählt, dass die Funktion zu seinem Konto(zum Objekt) führt. (Später existieren mehrere Konten der Klasse "Konto".
Nun frage ich mich, wie soll ich anhand einer Funktion wie in Konto.cpp → void kontostatus(Konto& knt_nr) das richtige Objekt identifizieren können? Oder sollte ich die Objekte meiner Klasse in Kontonummern umwandeln?
Vielleicht habt ihr eine bessere Idee.
Konto.h
Code:
// Definition der Klasse ''Konto''
#pragma once
#include <iostream>
#include <string>
class Konto
{
private:
std::string kontoinhaber;
unsigned long kontonummer;
unsigned long bankleitzahl;
double stand;
public:
//bool init_kunde(std::string&, unsigned long&); // Initialisiert die Kontonummer und den Namen des Kontoinhaber in das Objekt
void kontostatus(Konto&); // Zeigt alle Kontoinformationen an
Konto(double, unsigned long); // Konstruktor für Anfangswerte - Bankleitzahl und Kontostand
Konto(std::string&); //
};
Konto.cpp
Code:
// Zunächst Konstruktoren mit Anfangswerten definieren
#include "Konto.h"
//###############Alle Konstruktoren für die Klasse "Konto"//###############
//#########################################################################
//#########################################################################
Konto::Konto(double kontostand = 0.00,unsigned long bankleitzahl = 669503499) // Konstruktor → Für Anfangswerte: Kontostand und Bankleitzahl
{}
Konto::Konto(std::string& name) // Hier wird der eingegebene Name überprüft ob ungueltig oder zu klein.
{
if(name.size() <= 4) // Der eingegeben Name muss größer als 4 Zeichen sein.
{
std::cout << "Der eingegebene Name ist ungueltig oder zu klein";
}
}
//##################Alle Methoden für die Klasse "Konto"//#################
//#########################################################################
//#########################################################################
void kontostatus(Konto& knt_nr) // Zeigt alle Kontoinformationen an
{
}
Main.cpp
Code:
// Die Mainfunktion vom Programm // main.cpp
#include "Konto.h"
bool static objekt_erzeugen();
int hauptfunktion(){
std::cout << "#############################################################################" << std::endl;
std::cout << "#############################__Haupt__Menue__###############################" << std::endl;
std::cout << "###########################__Kontoverwaltung__###############################" << std::endl;
std::cout << "#############################################################################" << std::endl << std::endl << std::endl;
std::cout << "Waehlen Sie einen Menuepunkt aus - Geben Sie hierbei die Nummer die vorrangestellt wurde ein." << std::endl;
std::cout << "[1] Account erstellen - [2] Kontouebersicht - [3] Einzahlung auf Bankkonto - [4] Auszahlung aus Bankkonto" << std::endl;
int eingabe_menue; // eingabe_menue ist für die Menüfunktion
std::cin >> eingabe_menue;
std::cin.sync();
std::cin.clear();
switch(eingabe_menue)
{
case 1: { /* Es wird nach dem Namen gefragt und das Konto erstellt*/
std::string name_eingabe;
std::cout << "Ihr vollstaendiger Name: ";
std::string name_eingabe;
Konto kunde1(name_eingabe);
getline(std::cin, name_eingabe) >> name_eingabe;
std::cout << "Ihre Eingabe war erfolgreich" << std::endl;
break;
}
case 2: { /* Kontoübersicht - Inhaber, Kontostand wird angezeigt */
}
Ich hab da ausversehen eine Anweisung falsch einsortiert.
Code:
getline(std::cin, name_eingabe) >> name_eingabe;
Konto kunde1(name_eingabe);
std::cout << "Ihre Eingabe war erfolgreich" << std::endl;
Edit:// Ich verstehe nicht ganz das Union im Speicher. Datenelemente die mit Union definiert wurden, bekommen die gleiche Speicherschnittstelle(Anfangsadresse halt kenn kein anderes Wort dafür  ).
Wie berechnet man da die Größe eines Objekts? Die Bitoperatoren habe ich auch nicht gerade sehr gut drauf... Hab mich aber auch nicht intesiv damit beschäftigt.
|
|
|
08/22/2012, 19:51
|
#25
|
elite*gold: 5
Join Date: Sep 2006
Posts: 385
Received Thanks: 218
|
Ohje, da stimmt so einiges nicht.
Vorweg:
Du rückst noch immer nicht sauber ein. Nach jedem { rückst du ein und ab jedem } wieder eins zurück (das gilt auch für einzeilige ifs und Schleifen).
Code:
void foo()
{
if(false)
std::cout << std::endl;
while(true)
{
if(true)
{
break;
}
}
std::cout << std::endl;
}
Nun zu den Fehlern:
Code:
void kontostatus(Konto&);
Da ist der Parameter unnötig.
Code:
void Konto::zeigeKontostand() //kontostatus ist kein geeigneter Name
{
std::cout << this->kontoinhaber << "\n\t"
<< this->kontonummer << "\t" << this->bankleitzahl << "\n\t"
<< this->stand << std::endl;
}
Das this-> kannst du dir auch sparen, aber da deine klassenattribute kein "m"-Prefix haben, macht es verständlicher woher die Variablen kommen.
Code:
Konto::Konto(double kontostand = 0.00,unsigned long bankleitzahl = 669503499)
{}
Hier hast du zwar einen Konstruktor erstellt, aber die Klasse initialisieren tust du nicht. Du lässt dir zwei Parameter übergeben, die dann auch noch optional sind und das war es dann.
Was du machen willst ist folgendes:
Code:
Konto::Konto(double kontostandNeu = 0.00,unsigned long bankleitzahlNeu = 669503499) : // : leitet die initializer list ein
kontostand(kontostandNeu), //schreibt den Werten von kontostandNeu in das Attribut "kontostand"
bankleitzahl(bankleitzahlNeu) //schreibt den Werten von bankleitzahlNeu in das Attribut "bankleitzahl"
{
}
Identifizieren musst du da nichts, schließlich legst du ja eine Instanz der Klasse an, die die Daten für sich selber Verwaltet.
Code:
class Foo
{
private:
int mBar;
public:
Foo(int bar) :
mBar(bar)
{
}
int getBar()
{
return mBar;
}
void setBar(int bar)
{
mBar = bar;
}
};
int main()
{
Foo fooUno(10);
Foo fooDue(5);
Foo fooTre(10);
std::cout << fooUno.getBar() << std::endl;
std::cout << fooDue.getBar() << std::endl;
std::cout << fooTre.getBar() << std::endl;
fooTre.setBar(-1);
std::cout << fooTre.getBar() << std::endl;
}
Wie du siehst, verwaltet jede Instanz ihre eigene mBar Variable.
Quote:
Edit:// Ich verstehe nicht ganz das Union im Speicher. Datenelemente die mit Union definiert wurden, bekommen die gleiche Speicherschnittstelle(Anfangsadresse halt kenn kein anderes Wort dafür ).
Wie berechnet man da die Größe eines Objekts? Die Bitoperatoren habe ich auch nicht gerade sehr gut drauf... Hab mich aber auch nicht intesiv damit beschäftigt.
|
Der Trick am Union ist, dass du nicht mehrere Variablen damit erstellst, sondern nur genau eine! Diese wird jedoch nur anders interpretiert, unter den Typen im Union.
Code:
union useless
{
float fValue;
unsigned long ulValue;
};
int main()
{
useless u;
u.ulValue = 0x40a00000;
std::cout << std::hex << u.fValue << std::endl;
}
Nehmen wir an useless liegt im Speicher an der Stelle 0xDEADBEEF. Die Größe des Unions richtet sich immer am größten Datentypen in der Union und da sizeof(float) == sizeof(unsigned long) == 4 ist, belegt useless ebenfalls 4 Bytes.
Auf diese 4 Bytes schreiben wir nun den Werten 0x40A00000 (1084227584) und lassen uns danach die float Repräsentation des Werten ausgeben. 0x40A00000 repräsentiert den Float Werten 5.0.
Was ich in meinem anderen Beitrag gemacht habe ist, dass ich es ausgenutzt habe, dass sich die Größe der Union immer nach den größten Datentypen richtet.
Code:
union word //1 word == 2 bytes
{
struct
{
byte low;
byte high;
};
unsigned short value;
};
Diese union ist 2 Bytes groß und value beinhaltet z.B. einen Werten wie 0xAAFF. Binär sieht der Wert so aus:
Code:
10101010 11111111
Byte1 Byte2
Die obere Hälfte ist der so genannte high part und die untere hälfte der low part.
und im Arbeitsspeicher dann so (little endian):
11111111 10101010
Im union ist ebenfalls ein struct mit zwei bytes. Dieses struct liegt nun auf der selben Adresse, doch da es nicht aus einem unsigned short, sondern zwei bytes besteht, wird die Adresse nicht als unsigned short, sondern als zwei Bytes ausgewertet. Dadurch erhalte ich direkten Zugriff auf die beiden Bytes.
Code:
im ram
11111111 10101010
low high
0xAA 0xFF
Aber das würde ich schon als ziemlich fortgeschrittene Materie bezeichnen. Ich denke als Anfänger musst du das nicht auf anhieb verstehen.
PS:
Ich gebe ihm bewusst nicht die Lösung. Er soll das Problem ja schließlich zu verstehen lernen und es somit aus eigener Anstrengung heraus bewältigen.
|
|
|
08/23/2012, 00:01
|
#26
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
|
Quote:
Originally Posted by Nightblizard
Das kann ich so nicht stehen lassen. unions haben, wie jedes andere Mittel der Sprache, einen Grund, warum sie existieren. Und nur weil du ihn (noch) nicht kennst oder falsch kennen gelernt hast, heißt das nicht, dass das "Schrott" ist.
|
Hab ich auch nicht gesagt.
Ich sagte, dass sie selten verwendet werden und auch in irgendeinem C++ Artikel hab ich mal davon gelesen, dass davon abgeraten wird.
Finde den Artikel nicht mehr. Kann auch sein, dass ich damals was falsch verstanden hab oder es sich auf eine spezifische Schreibweise bezog. Ist schon etwas länger her.
Denn Sinn kenne ich sehr wohl.
Btw. deine Beispiele setzen das Little Endian Format voraus, dementsprechend sind sie nicht plattformunabhängig.
|
|
|
08/23/2012, 13:11
|
#27
|
elite*gold: 0
Join Date: Jul 2012
Posts: 56
Received Thanks: 5
|
Ich denke der Ansatz ist jetzt vorhanden.
Auf was bezog sich das hier:
Quote:
|
Die obere Hälfte ist der so genannte high part und die untere hälfte der low part.
|
Die Lösung auf was o.ô?
Quote:
|
Ich gebe ihm bewusst nicht die Lösung.
|
Das sie, wie Mr. Smith geschrieben hat, nicht mehr plattformunabhängig sind?
Woher weiß ich, das A den dezimalen Wert 10 hat? ASCII-Tabelle ist A mit dem Wert 65 beschmückt.
Edit:// Hab nicht dran gedacht, an die Hexadezimalen zu denken xD
Quote:
|
Adresse nicht als unsigned short, sondern als zwei Bytes ausgewertet.
|
Ich weiß nicht, wie ich das interpretieren soll.
Unsigned Short ist ein Datentyp mit einer Größe von: 2 Bytes.
Statt des obrigen Datentyps nehme ich int: 4 Bytes.
Wird es als 4 Bytes ausgewertet oder weiterhin als 2 Bytes (Low-Highbyte)?
Verstehen würde ich es dennoch, wie das ganze Zusammengesetzt wird.
Wenn ich nun auf den Wert 0xAAFF zugreifen möchte, kann ich einzelnd auf 0xAA oder 0xFF zugreifen und davor ist es nicht möglich oder wie?
Das es was zu bemängeln gibt wusste ich von vorne rein, aber das lässt sich bei nie vermeiden. Ich denke das liegt daran, dass ich ständig nur lese und weniger Übungen mache...
Zum wesentlichen
this und "m"-Prefix das hatte ich noch nicht. Ich werds mir aber merken.
Code:
Konto::Konto(double kontostandNeu = 0.00,unsigned long bankleitzahlNeu = 669503499) : // : leitet die initializer list ein
kontostand(kontostandNeu), //schreibt den Werten von kontostandNeu in das Attribut "kontostand"
bankleitzahl(bankleitzahlNeu) //schreibt den Werten von bankleitzahlNeu in das Attribut "bankleitzahl"
{
}
Ist es wichtig, die Paramater einen abweichenden Namen zu geben?
Ich will ja, wenn der das Konto anlegt, dass die Bankleitzahl und der Anfangsbestand von 0.00 € in die Datenelemente "Bankleitzahl und Kontostand" gespeichert wird.
Der Konstruktor wird ja nur einmal und zwar beim erzeugen des Objekts ausgeführt. Dann kann ich statt bankleitzahlNeu auch nur bankleitzahl benutzen. Oder kollidiert es?
Das mit den "Einrückungen" war absichtlich. Ich fand es so übersichtlicher, aber ich sehe nun was du gemeint hast und werde es mal beibehalten.
Edit:// Ach das hat er mit m-Präfix gemeint.
|
|
|
08/23/2012, 13:50
|
#28
|
elite*gold: 0
Join Date: Feb 2012
Posts: 115
Received Thanks: 18
|
Quote:
Originally Posted by Hg(CNO)2
Ist es wichtig, die Paramater einen abweichenden Namen zu geben?
Ich will ja, wenn der das Konto anlegt, dass die Bankleitzahl und der Anfangsbestand von 0.00 € in die Datenelemente "Bankleitzahl und Kontostand" gespeichert wird.
Der Konstruktor wird ja nur einmal und zwar beim erzeugen des Objekts ausgeführt. Dann kann ich statt bankleitzahlNeu auch nur bankleitzahl benutzen. Oder kollidiert es?
|
Wenn deine membervariable auch bankleitzahl heißt, kannst du dann innerhalb des Konstruktors nurmehr mit this->bankleitzahl auf die Membervariable zugreifen, da sonst der Parameter gemeint ist. Sieht dann so aus: this->bankleitzahl = bankleitzahl;
Stattdessen kannst du auch deine Membervariable m_bankleitzahl nennen, dann brauchst du kein this verwenden: m_bankleitzahl = bankleitzahl;
|
|
|
08/23/2012, 15:27
|
#29
|
elite*gold: 0
Join Date: Jul 2012
Posts: 56
Received Thanks: 5
|
Ich verstehe grad deinen Satz nicht tut mir wirklich leid.
Der Punkt hier sorgt für Verwirrung:
Quote:
|
innerhalb des Konstruktors nurmehr mit this->bankleitzahl
|
nurmehr?? Du musst dich etwas klar ausdrücken. Ich kann leider nicht verstehen, was du mir verständlich machen willst.
Dieser Doppelpunkt was bedeutet der? Das wurde in meinem Buch nicht erwähnt.
Code:
EineKlasse::EineKlasse()
: m_eineVariable(0)
{
}
Die Sache mit dem Doppelpunkt hat sich erledigt.
|
|
|
08/23/2012, 21:53
|
#30
|
elite*gold: 5
Join Date: Sep 2006
Posts: 385
Received Thanks: 218
|
Quote:
Originally Posted by MrSm!th
und auch in irgendeinem C++ Artikel hab ich mal davon gelesen, dass davon abgeraten wird.
|
Und andere raten immer und überall von goto ab. Doch auch das hat seine Anwendungsbereiche. (mal schauen ob ich jetzt gesteinigt werde)
Zieht die Scheuklappen aus, das macht das Leben sehr viel leichter.
Quote:
Originally Posted by MrSm!th
Btw. deine Beispiele setzen das Little Endian Format voraus, dementsprechend sind sie nicht plattformunabhängig.
|
Meh, das kannst du auch umgehen, doch hat das jetzt wenig mit dem konkreten Beispiel am Hut. Zumal Mainstream CPUs so oder so den Little Endian nutzen.
Quote:
Originally Posted by Hg(CNO)2
Ich denke der Ansatz ist jetzt vorhanden.
Auf was bezog sich das hier:
|
Der Teil bezog sich auf die Bits im Arbeitsspeicher.
Zahl: 0xF0 (240)
Little Endian: 1111 0000
Big Endian: 0000 1111
1111 ist der low Part
0000 ist der high Part
Aber wie gesagt, das ist recht fortgeschritten, das musst du jetzt noch nicht wissen.
Quote:
Originally Posted by Hg(CNO)2
Die Lösung auf was o.ô?
|
Der Auszug bezog sich darauf, dass ich keine Beispiele mit deinem Code mache, bzw. ihn sogar für dich korrigiere.
Dadurch lernst du nichts, deshalb mache ich das nicht.
Bezog sich auch nicht auf dich, sondern eher auf die Leute, die hier die sofort Lösungen bereitstellen.
Quote:
Originally Posted by Hg(CNO)2
Das sie, wie Mr. Smith geschrieben hat, nicht mehr plattformunabhängig sind?
|
Nein und wie ich bereits oben geschrieben habe, lässt sich das auch umgehen. Also nicht weiter tragisch.
Quote:
Originally Posted by Hg(CNO)2
Ich weiß nicht, wie ich das interpretieren soll.
|
Ist auch nicht sehr einfach das zu erklären.
Quote:
Originally Posted by Hg(CNO)2
Unsigned Short ist ein Datentyp mit einer Größe von: 2 Bytes.
Statt des obrigen Datentyps nehme ich int: 4 Bytes.
Wird es als 4 Bytes ausgewertet oder weiterhin als 2 Bytes (Low-Highbyte)?
|
Dann wird es als 4 Bytes ausgewertet und low und high stellen dann den low und high Teil der unteren 2 Bytes der 4 Bytes dar. Hast du jedoch z.B. eine Motorola CPU (die nutzen den Big Endian), dann verdreht sich hier alles. Das wäre dann tatsächlich einfach nur falsch.
Ich versuche das mal grafisch darzustellen, vielleicht kann ich es so besser erklären.
value belegt alle 4 Bytes und high und low werden auf die oberen zwei und unteren zwei Bytes gelegt.
Quote:
Originally Posted by Hg(CNO)2
Wenn ich nun auf den Wert 0xAAFF zugreifen möchte, kann ich einzelnd auf 0xAA oder 0xFF zugreifen und davor ist es nicht möglich oder wie?
|
Klar, jedoch ist das nicht ganz so verständlich auf den ersten Blick.
Code:
unsigned short foo = 0xFFAA;
unsigned short low = foo & 0xff;
unsigned short high = foo >> 8;
Quote:
Originally Posted by Hg(CNO)2
Das es was zu bemängeln gibt wusste ich von vorne rein, aber das lässt sich bei nie vermeiden. Ich denke das liegt daran, dass ich ständig nur lese und weniger Übungen mache...
|
Das sah bei niemanden anders aus, als er programmieren lernte. Lass dich deswegen nicht entmutigen, das kommt alles mit der Zeit.
Quote:
Originally Posted by Hg(CNO)2
Zum wesentlichen
this und"m"-Prefix das hatte ich noch nicht. Ich werds mir aber merken.
|
Macht dein Programm einfach nur lesbarer. Wird deshalb wahrscheinlich nicht in deinem Buch genauer erläutert.
Quote:
Originally Posted by Hg(CNO)2
Ist es wichtig, die Paramater einen abweichenden Namen zu geben?
Ich will ja, wenn der das Konto anlegt, dass die Bankleitzahl und der Anfangsbestand von 0.00 € in die Datenelemente "Bankleitzahl und Kontostand" gespeichert wird.
Der Konstruktor wird ja nur einmal und zwar beim erzeugen des Objekts ausgeführt. Dann kann ich statt bankleitzahlNeu auch nur bankleitzahl benutzen. Oder kollidiert es?
|
Du musst das nicht machen, der Compiler würde das verstehen. Jedoch ist das wieder so ein Ding, um dein Programm verständlich zu machen; benenn dein Zeug anständig, das wird dir viel ärger ersparen.
|
|
|
 |
|
Similar Threads
|
[HowTo]Objekte, Waffen und Rüssis für Metin2 mit 3DS MAX 7 erstellen
01/18/2015 - Metin2 PServer Guides & Strategies - 98 Replies
GR2 To Mesh
Wird hier erklärt
Klick mich
In dieser Anleitung werde ich erklären wie man ein eigenes Schwert in 3D Studio MAX modelliert, texturiert (mit vorgefertigter Textur), exportiert und für Metin2 nutzbar macht. Also der ganze Ablauf um komplett neue eigene Waffen oder auch andere Objekte für Metin2 zu erstellen.
Dabei verwende ich 3ds max 7 Trial, welches für zunächst 30 Tage kostenlos zu nutzen ist, vielleicht funtkioniert das meiste auch mit gmax (kostenlos) mit ein paar...
|
C++ / Array in einer Klasse
06/21/2012 - C/C++ - 9 Replies
Hi Leute!
Ich erstelle das Objekt "ElevatorControl" genau einmal. Zu einem späteren Zeitpunkt erstelle ich ein oder mehrere Objekte von "ElevatorCabin" und möchte die Adressen von "ElevatorCabin" in dem Array "elevators","elevators", usw. speichern. Leider habe ich eine totale Denkblockade und komme einfach nicht drauf wie ich dass hinbekommen soll. Ich hoffe jemand von euch kann mir helfen.
//ElevatorControl.h
class ElevatorControl {
public:
void requestUpward(int atLevel);
void...
|
[C++] Vraiblen einer KLasse in die Funktion einer anderen einfügen
03/14/2011 - C/C++ - 10 Replies
Hallo Leute,
Ich habe mal wieder eine Frage :D
Ich bin gerade dabei ein kleines Spiel(noch ist es klein ;D) zu programmieren.
Dabei bin ich auf das Problem gestoßen, dass ich gerne die Verteidigung der "User" Class in eine Berechnung(Funktion) einer "Npc" Class einbinden würde. Dies funktioniert aber weder durch:
-Einführen einer Funktion in der User class die eine Variable returned die den selben Wert besitzt, wie die Variable der Verteidigung in der Userclass
-Direktes Aufrufen der...
|
[Frage]3D-Objekte erstellen
12/05/2010 - Minecraft - 4 Replies
Hey Leute,
Ich wollte mal fragen mit welchen Programm man beispielsweise das 3D Objekt der Schaufel umwandeln kann :)..!
bzw. genauer erklärt haben wie Minecraft umgewandelte Texturen annimmt weil ich mir ne versäcuhte Welt aufbauen wollte(dunkel grünes Wassser etc.)
mfg Mine
|
[C++]Funktion einer Klasse in einer anderen Funktion der Klasse verwenden, aber wie?
07/25/2010 - C/C++ - 3 Replies
Mein Problem ist eigentlich recht simpel und die Lösung wahrscheinlich auch.
Da ich bisher fast 0 mit Klassen am Hut hatte, wollte ich mich doch mit dem Thema anfreunden und hatte gleich angefangen:
int test::Funktion2()
{
int temp;
cin>>temp;
return temp;
}
|
All times are GMT +1. The time now is 11:36.
|
|