Willkommen im #Neuland
Login wie bei quake.ingame.de zuvor, die Passwörter aus der alten Datenbank wurden aber gelöscht - einmal hier neu anfordern.
Wer seine E-Mail-Adresse nicht mehr hat oder kennt, bitte eine Nachricht mit Infos schicken o. im Discord melden.

PQ Discord Server: #planetquake                                                                                                                                         Spenden? Hier entlang!

C++ Dekonstruktor

Forum für alles rund ums Coden und web.design - HTML, XHTML, XML, CSS, PHP, ASP, Zugriffsrechten, Mods uvm.
Antworten
Wyx
Angel
Angel
Beiträge: 527
Registriert: Nov 2001

C++ Dekonstruktor

Beitrag von Wyx »

Hallo Leute hab hier kleines C++ Programm. Hab hier aber ein kleines Dekonstruktor Problem...
Ich hab ein Array, welches auf die Instanzen von meiner Klasse zeigt. Aber leider es einmal doppelt auf eine Instanz. Wenn ich die zerstöre, dann haut es ihn natürlich auf wenn ich es nochmal machen möchte...
freund[5] und freund[3] zeigen beide auf luisa
Irgendwer eine Idee?


Hier mal das Programm.

Code: Alles auswählen

#include <iostream>
using namespace std;

int strlen1(const char *str) { // liefert die Laenge von str
if (str==0) return 0;
int i=0;
for (; str[i]; ++i);
return i;
}

void strcpy1(const char *src, char *dest) { // kopiert Inhalt von src nach dest
if (src==0 || dest==0) return;
int i=0;
for (; src[i]; ++i) dest[i]=src[i];
dest[i]='\0';
}

class Person {
char *name;
public:
Person(const char *str = "Susi") {
name = new char[strlen1(str)+1];
strcpy1(str,name);
}
Person(const Person &p) {
name = new char[strlen1(p.name)+1];
strcpy1(p.name,name);
}
~Person() { if(name) delete name;}

void change() {
name[4]='e';
}
ostream &print(ostream &o) const {
o<<name;
return o;
}
};

int main() {
Person maria("Maria"), peter("Peter"), franz("Franz"), luisa("Luisa");
Person mary(maria);
Person luise;
Person p(luise);
Person *freunde = new Person[7];
freunde[0]=maria;
freunde[1]=peter;
freunde[2]=franz;
freunde[3]=luisa;
freunde[4]=mary;
freunde[5]=luise;
freunde[6]=p;
freunde[5]=luisa;
freunde[3].change();
freunde[4].change();
for (int i=0; i<7; ++i) {
freunde[i].print(cout);
cout<<endl;
}
for (int i=0; i<7; ++i) 
	freunde[i].~Person();
_getchar_nolock();
return 0;
}
CTCooL
Cadavre
Cadavre
Beiträge: 3415
Registriert: Jul 2001
Wohnort: Magdeburg
Steam: CTCooL
Kontaktdaten:

Beitrag von CTCooL »

NULL-Terminiere den Pointer, packe dies in den Destruktor, bevor du den pointer killst: name = '\0';
Bild
"Holla, das ist mal 'n Käffchen.. Latte Macchiato ist ja auch.. eeh.. italienisch für Errektion!"
CTCooL @ deviantart
#pq.sc2
Wyx
Angel
Angel
Beiträge: 527
Registriert: Nov 2001

Beitrag von Wyx »

also du meinst einfach so.

Code: Alles auswählen

~Person() {name='\0'; delete name;}
CTCooL
Cadavre
Cadavre
Beiträge: 3415
Registriert: Jul 2001
Wohnort: Magdeburg
Steam: CTCooL
Kontaktdaten:

Beitrag von CTCooL »

genau. bei mir hats gestern funktioniert :)
name = '\0';
delete [] name;
schreiben

und viel wichtiger: warum benutzt du nen pointer auf nen char anstatt gleich auf string zu gehen.
Der Weg über *char zu gehen ist C-Stil, nichts spricht gegen C++ strings, wenn du sowieso OOP.

und wie sieht dein quellcode eigentlich aus? das is kein cpp sondern sieht aus wie cpp im format c# :>

eigentlich sollte das so aussehen, was aber nichts an deinem problem ändernt :D zumindest die Klasse:

Code: Alles auswählen

class Person
{
	char *name;
    public:
	Person(const char *str = "Susi");
	Person(const Person &p);
	~Person();

	void change();
		
	ostream &print(ostream &o) const
	{
		o<<name;
		return o;
	}
};

Person::Person(const char *str = "Susi")
{
	name = new char[strlen1(str)+1];
	strcpy1(str,name);
}

Person::Person(const Person &p)
{
	name = new char[strlen1(p.name)+1];
	strcpy1(p.name,name);
}

Person::~Person()
{
	if(name)
	{
		name = '\0';
		delete[] name;
	}
}
Bild
"Holla, das ist mal 'n Käffchen.. Latte Macchiato ist ja auch.. eeh.. italienisch für Errektion!"
CTCooL @ deviantart
#pq.sc2
Nomschta
Rampage
Rampage
Beiträge: 14303
Registriert: Jun 2001
Steam: TomHonks

Beitrag von Nomschta »

format c#? das ist format scheisshaufen :ugly:
BildBild Danke an Drasora für ihr Wichtelgeschenk!
MAR hat geschrieben:Führt der durch den Terrence-Hill? :ugly:
CTCooL
Cadavre
Cadavre
Beiträge: 3415
Registriert: Jul 2001
Wohnort: Magdeburg
Steam: CTCooL
Kontaktdaten:

Beitrag von CTCooL »

ich wollte seriös wirken :ubla:
Bild
"Holla, das ist mal 'n Käffchen.. Latte Macchiato ist ja auch.. eeh.. italienisch für Errektion!"
CTCooL @ deviantart
#pq.sc2
Nomschta
Rampage
Rampage
Beiträge: 14303
Registriert: Jun 2001
Steam: TomHonks

Beitrag von Nomschta »

hat nich geklappt :D

immerhin besser als "coding styleguide: rund's edition"
BildBild Danke an Drasora für ihr Wichtelgeschenk!
MAR hat geschrieben:Führt der durch den Terrence-Hill? :ugly:
Wyx
Angel
Angel
Beiträge: 527
Registriert: Nov 2001

Beitrag von Wyx »

haha werde ich weiterleiten. :)
Ist nicht von mir programmiert sondern eine Musterprüfung für eine Klausur :ugly:
Hab da nur den Dekonstruktor machen müssen :P
CTCooL
Cadavre
Cadavre
Beiträge: 3415
Registriert: Jul 2001
Wohnort: Magdeburg
Steam: CTCooL
Kontaktdaten:

Beitrag von CTCooL »

jaja auf einmal ;)
Bild
"Holla, das ist mal 'n Käffchen.. Latte Macchiato ist ja auch.. eeh.. italienisch für Errektion!"
CTCooL @ deviantart
#pq.sc2
Roughael
Stripe
Stripe
Beiträge: 2498
Registriert: Mär 2002

Beitrag von Roughael »

@Title:
<klugscheissmodus>
Destruktor, nicht Dekonstruktor.
Du sagst doch auch nicht etwas ist dekonstruktiv, sondern etwas ist destruktiv.
</klugscheissmodus>

@Code:

Code: Alles auswählen

freunde[i].~Person();
Bild

...

Code: Alles auswählen

freunde[i].~Person();
:kotz:

Musterprüfung für eine Klausur
Oh Junge, ich würd die Hochschule/Uni/whatever wechseln.
Es gibt sehr sehr selten einen triftigen Grund einen Destruktor manuell aufzurufen.
Und hier ist das sicherlich nicht der fall.

maria, peter, franz, luisa, mary, luise, p sind keine dynamisch angelegten Instanzen, auf diese rufst du also schonmal keinen Destruktor auf.
Das wird automatisch für dich gemacht. Nur bei dynamisch angelegtem Speicher (new keyword) wird der Destruktor aufgerufen, und dort mal von sehr exotischen Fällen abgesehen nur über das delete keyword.

Code: Alles auswählen

Person *freunde = new Person[7];
Dies soll scheinbar eine liste der Personen sein, aber es werden hier 7 neue Instanzen der Klasse Person erzeugt.
Diesen wird dann später lediglich der Wert zugewiesen der in den vorher angelegten Instanzen gesetzt wurde.
Diese liste ist nun im dynamischen speicher, aber hier löscht man die einträge nicht einzeln via delete freunde; sondern alle zusammen mit delete[] freunde;

Ich gehe mal stark davon aus, dass der code so gemeint war:

Code: Alles auswählen

#include <iostream>
using namespace std;

int strlen1(const char *str) { // liefert die Laenge von str
    if (str == 0) return 0;
    int i = 0;
    for (; str[i]; ++i);
    return i;
}

void strcpy1(const char *src, char *dest) { // kopiert Inhalt von src nach dest
    if (src == 0 || dest == 0) return;
    int i = 0;
    for (; src[i]; ++i) dest[i] = src[i];
    dest[i] = '\0';
}

class Person {
    char *name;

public:

    Person(const char *str = "Susi") {
        name = new char[strlen1(str) + 1];
        strcpy1(str, name);
    }

    Person(const Person &p) {
        name = new char[strlen1(p.name) + 1];
        strcpy1(p.name, name);
    }

    ~Person() {
        if (name) delete[] name;
    }

    void change() {
        name[4] = 'e';
    }

    ostream & print(ostream & o) const {
        o << name;
        return o;
    }
};

int main() {
    Person *maria = new Person("Maria"), *peter = new Person("Peter"), *franz = new Person("Franz"), *luisa = new Person("Luisa");
    Person *mary = new Person(*maria);
    Person *luise = new Person();
    Person *p = new Person(*luise);
    Person **freunde = new Person *[7];
    freunde[0] = maria;
    freunde[1] = peter;
    freunde[2] = franz;
    freunde[3] = luisa;
    freunde[4] = mary;
    freunde[5] = luise;
    freunde[6] = p;
    freunde[5] = luisa;
    freunde[3]->change();
    freunde[4]->change();
    for (int i = 0; i < 7; ++i) {
        freunde[i]->print(cout);
        cout << endl;
    }
    for (int i = 0; i < 7; ++i)
        delete freunde[i];
    delete[] freunde;
    _getchar_nolock();
    return 0;
}
Aber auch das ist noch falsch, denn hier könnte man einen Eintrag doppelt löschen.
Und wenn du einen Array nimmst in dem eine Instanz mehrfach vorkommen kann bedeutet auch dass die Instanz eventuell gar nicht drin vorkommt. Bam! => Memory Leak.

Hier gibt es drei Mögliche Lösungen:

1. Smart Pointer
2. Halte dir eine Liste der (eindeutigen) Instanzen.
3. Jede Instanz für sich deleten.


Auf gar keinen Fall einen Destruktor mehrfach aufrufen, absolutes No-Go.
Und schon gar nicht auf Instanzen die nicht dynamisch angelegt wurden.

Sollte es einfach nur um eine ausgabe einer Freundesliste gegangen sein, so wäre es auch so gegangen:

Code: Alles auswählen

#include <iostream>
using namespace std;

int strlen1(const char *str) { // liefert die Laenge von str
...
}

void strcpy1(const char *src, char *dest) { // kopiert Inhalt von src nach dest
...
}

class Person {
...
};

int main() {
    Person maria("Maria"), peter("Peter"), franz("Franz"), luisa("Luisa");
    Person mary(maria);
    Person luise;
    Person p(luise);
    Person **freunde = new Person *[7];
    freunde[0] = &maria;
    freunde[1] = &peter;
    freunde[2] = &franz;
    freunde[3] = &luisa;
    freunde[4] = &mary;
    freunde[5] = &luise;
    freunde[6] = &p;
    freunde[5] = &luisa;
    freunde[3]->change();
    freunde[4]->change();
    for (int i = 0; i < 7; ++i) {
        freunde[i]->print(cout);
        cout << endl;
    }
    delete[] freunde; //löscht lediglich den array, nicht die personen.
    _getchar_nolock();
    return 0;
    // Nach beendung von main() werden die personen automatisch gelöscht, da nicht über new angelegt.
}
<-- Ehemaliger TTK-Bandit, bis inquake rumzickte -->

Dict.cc Firefox Addon | Q3Devel | Code3Arena(De) | GameType Revolution | Open Game Libraries
Wyx
Angel
Angel
Beiträge: 527
Registriert: Nov 2001

Beitrag von Wyx »

Okay, also danke schonmal für die Hilfe.

Also nur das ganze Array löschen mittels

Code: Alles auswählen

delete[] freunde;
muss ich dann noch irgendwas in den Destruktor von der Klasse Person machen?
z.B.:?

Code: Alles auswählen

 ~Person() {
       name='\0';
       delete[] name;
    }
Und falls noch jemand Zeit und Muse hat könnte er mir vielleicht bei noch einer Frage kurz weiterhelfen?

Ich hab da jetzt was anderes programmiert... das läuft auf Windows in meinem Visual Studio ohne Probleme, aber wenn ich es in Linux mittels Vim und G++ compiliere läuft es nicht.
Hier der Code

Code: Alles auswählen

#include <iostream>
using namespace std;

//waehrungssymbole
enum waehrung{USD,EUR,CHF,CAD};

//wechselkurs
double wechselTabelle[4]={1, 0.754375377 , 0.909297568, 0.992004444};

class BarWert{
	private:
		waehrung _waehrung;
		double _wert;
	public:
		BarWert();
		BarWert(waehrung w, double x);

		double getWert();
		waehrung getWaehrung();
};
class Konto{
	private:
		waehrung _waehrung;
		double _wert;
		double _dispo;
	public:
		Konto();
		Konto(BarWert bw);
		Konto(waehrung w);
		Konto(waehrung w, double x, double d);

		double getWert();
		waehrung getWaehrung();
		double getDispo();

		bool umbuchen(double betrag, Konto &von);

		void operator+=(BarWert& bw);
		void operator-=(BarWert& bw);
		bool operator==(Konto& k);
};

ostream& operator<<(ostream& out, Konto& k){
	out<<"["<<k.getWaehrung()<<" "<<k.getWert()<<"/"<<k.getDispo()<<"]";
	return out;
};

ostream& operator<<(ostream& out, BarWert& bw){
	out<<bw.getWaehrung()<<" "<<bw.getWert();
	return out;
};

Konto::Konto(){
	_waehrung=EUR;
	_wert=0;
	_dispo=500;
}
Konto::Konto(waehrung w)
{
	_waehrung=w;
	_wert=0;
	_dispo=500;
}
Konto::Konto(BarWert bw){
	_waehrung=bw.getWaehrung();
	_wert=bw.getWert();
	_dispo=500;
}
Konto::Konto(waehrung w, double x, double d){
	_waehrung=w;
	if(d < 0)
		throw 1;
	if(d*(-1)>=x)
		throw 1;
	_wert=x;
	_dispo=d;
}

bool Konto::umbuchen(double betrag, Konto& von)
{
	double betragk=betrag/wechselTabelle[this->getWaehrung()] *wechselTabelle[von.getWaehrung()];
	if (this->_dispo*(-1)> this->getWert() + betrag || von._dispo *(-1) > von.getWert()-betrag)
		return false;
	else
	{
		this->_wert+=betrag;
		von._wert-=betrag;
		return true;
	}
}

void Konto::operator+=(BarWert& bw)
{
	double betrag=bw.getWert()/wechselTabelle[bw.getWaehrung()] * wechselTabelle[this->getWaehrung()];
	this->_wert+=betrag;
}

void Konto::operator-=(BarWert& bw)
{
	double betrag=bw.getWert()/wechselTabelle[bw.getWaehrung()] * wechselTabelle[this->getWaehrung()];
	this->_wert-=betrag;
}

bool Konto::operator==(Konto& k)
{
	double betrag=k.getWert()/wechselTabelle[k.getWaehrung()] * wechselTabelle[this->getWaehrung()];
	return (this->_wert==betrag);
}

double Konto::getWert(){
	return this->_wert;
}

double Konto::getDispo(){
	return this->_dispo;
}

waehrung Konto::getWaehrung(){
	return this->_waehrung;
}

BarWert::BarWert(){
	_waehrung=EUR;
	_wert=10;
}
BarWert::BarWert(waehrung w, double x ){
	_waehrung=w;
	if(x >0)
		_wert=x;
	else
		throw 1;
}

double BarWert::getWert(){
	return _wert;
}
waehrung BarWert::getWaehrung(){
	return _waehrung;
}

int main(){
	BarWert wert(USD,250);
	try{
		BarWert(USD,-10);
	}
	catch(...){
		cout <<"negativer Betraege in BarWert nicht erlaubt"<<endl;
	}
	try{
		Konto(EUR,100,-10);
	}
	catch(...){
		cout<<"negativer Dispo nicht erlaubt"<<endl;
	}
	try{
		Konto(EUR,-500,10);
	}
	catch(...){
		cout<<"konto ueberzogen"<<endl;
	}
		cout<<Konto(EUR,-500,1000)<<endl;

	Konto k(EUR,250,1000);
	cout<<k<<endl;
	k+=wert;
	cout<<k<<endl;
	Konto k1(EUR,250,1000);
	Konto k2(USD,10,1000);
	if (k1.umbuchen(250,k2))
		cout<<k1<<','<<k2<<endl;
	if (k1.umbuchen(1000,k2))
		cout<<k1<<','<<k2<<endl;
	if (k1.umbuchen(-250,k2))
		cout<<k1<<','<<k2<<endl;
	if (k1.umbuchen(-1251,k2))
		cout<<k1<<','<<k2<<endl;
	if (k1==k2) cout <<"k1 gleich k2"<<endl;
	Konto k3(USD,0,1000);
	k3+=BarWert(EUR,250);
	if(k1==k3) cout <<"k1 gleich k3"<<endl;
	cout <<k3 <<endl;
	BarWert bw;
	Konto k4;
	Konto k5(USD), k6(bw);
	cout<<bw<<endl<<k4<<endl<<k5<<endl<<k6<<endl;
	_getchar_nolock();
	return 0;
}
Und hier was der Compiler unter Linux meint.

Code: Alles auswählen

|| /home/schurdl/cpp/konto.cpp: In function ‘int main()’:
konto.cpp|161 col 28 error| no match for ‘operator<<’ in ‘std::cout << Konto((waehrung)1u, -5.0e+2, 1.0e+3)’
konto.cpp|161 col 28| note: candidates are:
|| In file included from /usr/include/c++/4.7/iostream:40:0,
||                  from /home/schurdl/cpp/konto.cpp:1:
... usw.
Falls wer die ganze File braucht dann lade ich sie später hoch

Danke schonmal an alle! :)
Roughael
Stripe
Stripe
Beiträge: 2498
Registriert: Mär 2002

Beitrag von Roughael »

"name='\0';" bevor "delete[] name;" funktioniert nicht.
Das ist als bekommst du ne Anweisung nen Wagen zu zerschrotten, aber bevor du es machst löscht du die Wagennummer von der Anweisung und vergisst sie zudem.

_getchar_nolock(); gibt es unter Linux (bzw. gcc) nicht. Versuchs mal mit getchar() statt dessen.
Hat nichts mit Linux zu tun wenn du Microsoft Funktionen nutzt anstelle der Ansi Standards.

Die Variable betragk wird nicht genutzt, sicher nicht gewollt ?

Membervariablen mit einem Unterstrich zu prefixen ist zwar kein Fehler aber unglaublich hässlich.

Was den Rest angeht, versuch mal wo angebracht das Schlüsselwort const einzusetzen:

Code: Alles auswählen

#include <iostream>
#include <stdio.h>
using namespace std;

//waehrungssymbole
enum waehrung{USD,EUR,CHF,CAD};

//wechselkurs
double wechselTabelle[4]={1, 0.754375377 , 0.909297568, 0.992004444};

class BarWert{
	private:
		waehrung _waehrung;
		double _wert;
	public:
		BarWert();
		BarWert(waehrung w, double x);

		double getWert() const;
		waehrung getWaehrung() const;
};
class Konto{
	private:
		waehrung _waehrung;
		double _wert;
		double _dispo;
	public:
		Konto();
		Konto(const BarWert &bw);
		Konto(waehrung w);
		Konto(waehrung w, double x, double d);

		double getWert() const;
		waehrung getWaehrung() const;
		double getDispo() const;

		bool umbuchen(double betrag, Konto &von);

		void operator+=(const BarWert& bw);
		void operator-=(const BarWert& bw);
		bool operator==(const Konto& k);
};

ostream& operator<<(ostream& out, const Konto& k){
	out<<"["<<k.getWaehrung()<<" "<<k.getWert()<<"/"<<k.getDispo()<<"]";
	return out;
};

ostream& operator<<(ostream& out, BarWert& bw){
	out<<bw.getWaehrung()<<" "<<bw.getWert();
	return out;
};

Konto::Konto(){
	_waehrung=EUR;
	_wert=0;
	_dispo=500;
}
Konto::Konto(waehrung w)
{
	_waehrung=w;
	_wert=0;
	_dispo=500;
}
Konto::Konto(const BarWert &bw){
	_waehrung=bw.getWaehrung();
	_wert=bw.getWert();
	_dispo=500;
}
Konto::Konto(waehrung w, double x, double d){
	_waehrung=w;
	if(d < 0)
		throw 1;
	if(d*(-1)>=x)
		throw 1;
	_wert=x;
	_dispo=d;
}

bool Konto::umbuchen(double betrag, Konto& von)
{
	double betragk=betrag/wechselTabelle[this->getWaehrung()] *wechselTabelle[von.getWaehrung()];
	if (this->_dispo*(-1)> this->getWert() + betrag || von._dispo *(-1) > von.getWert()-betrag)
		return false;
	else
	{
		this->_wert+=betrag;
		von._wert-=betrag;
		return true;
	}
}

void Konto::operator+=(const BarWert& bw)
{
	double betrag=bw.getWert()/wechselTabelle[bw.getWaehrung()] * wechselTabelle[this->getWaehrung()];
	this->_wert+=betrag;
}

void Konto::operator-=(const BarWert& bw)
{
	double betrag=bw.getWert()/wechselTabelle[bw.getWaehrung()] * wechselTabelle[this->getWaehrung()];
	this->_wert-=betrag;
}

bool Konto::operator==(const Konto& k)
{
	double betrag=k.getWert()/wechselTabelle[k.getWaehrung()] * wechselTabelle[this->getWaehrung()];
	return (this->_wert==betrag);
}

double Konto::getWert() const {
	return this->_wert;
}

double Konto::getDispo() const {
	return this->_dispo;
}

waehrung Konto::getWaehrung() const {
	return this->_waehrung;
}

BarWert::BarWert(){
	_waehrung=EUR;
	_wert=10;
}
BarWert::BarWert(waehrung w, double x ){
	_waehrung=w;
	if(x >0)
		_wert=x;
	else
		throw 1;
}

double BarWert::getWert() const {
	return _wert;
}
waehrung BarWert::getWaehrung() const {
	return _waehrung;
}

int main(){
	BarWert wert(USD,250);
	try{
		BarWert(USD,-10);
	}
	catch(...){
		cout <<"negativer Betraege in BarWert nicht erlaubt"<<endl;
	}
	try{
		Konto(EUR,100,-10);
	}
	catch(...){
		cout<<"negativer Dispo nicht erlaubt"<<endl;
	}
	try{
		Konto(EUR,-500,10);
	}
	catch(...){
		cout<<"konto ueberzogen"<<endl;
	}
		cout<<Konto(EUR,-500,1000)<<endl;

	Konto k(EUR,250,1000);
	cout<<k<<endl;
	k+=wert;
	cout<<k<<endl;
	Konto k1(EUR,250,1000);
	Konto k2(USD,10,1000);
	if (k1.umbuchen(250,k2))
		cout<<k1<<','<<k2<<endl;
	if (k1.umbuchen(1000,k2))
		cout<<k1<<','<<k2<<endl;
	if (k1.umbuchen(-250,k2))
		cout<<k1<<','<<k2<<endl;
	if (k1.umbuchen(-1251,k2))
		cout<<k1<<','<<k2<<endl;
	if (k1==k2) cout <<"k1 gleich k2"<<endl;
	Konto k3(USD,0,1000);
	k3+=BarWert(EUR,250);
	if(k1==k3) cout <<"k1 gleich k3"<<endl;
	cout <<k3 <<endl;
	BarWert bw;
	Konto k4;
	Konto k5(USD), k6(bw);
	cout<<bw<<endl<<k4<<endl<<k5<<endl<<k6<<endl;
	getchar();
	return 0;
}
<-- Ehemaliger TTK-Bandit, bis inquake rumzickte -->

Dict.cc Firefox Addon | Q3Devel | Code3Arena(De) | GameType Revolution | Open Game Libraries
CTCooL
Cadavre
Cadavre
Beiträge: 3415
Registriert: Jul 2001
Wohnort: Magdeburg
Steam: CTCooL
Kontaktdaten:

Beitrag von CTCooL »

Roughael hat geschrieben: ...
Membervariablen mit einem Unterstrich zu prefixen ist zwar kein Fehler aber unglaublich hässlich.
...
und ich dachte ich wäre der einzige der das so sieht :)
Bild
"Holla, das ist mal 'n Käffchen.. Latte Macchiato ist ja auch.. eeh.. italienisch für Errektion!"
CTCooL @ deviantart
#pq.sc2
Nomschta
Rampage
Rampage
Beiträge: 14303
Registriert: Jun 2001
Steam: TomHonks

Beitrag von Nomschta »

ist schon sehr praktisch wenn man exzessive OOP betreibt. ich hab das von nem kollegen übernommen und will es seitdem nicht mehr missen, insbesondere hinsichtlicht intellisense.
hässlich siehts aus, da stimm ich zu :D
BildBild Danke an Drasora für ihr Wichtelgeschenk!
MAR hat geschrieben:Führt der durch den Terrence-Hill? :ugly:
Wyx
Angel
Angel
Beiträge: 527
Registriert: Nov 2001

Beitrag von Wyx »

Danke Leute ihr seid mir eine große Hilfe.
Ich hab seit knapp 8-9 Jahren nicht mehr C++ programmiert und war auch nie wirklich der große Pro. Es ist zwar meistens alles gelaufen, aber von Coding-Standards hab ich überhaupt keine Ahnung.
Und jetzt nachdem ich lange nichts mehr gemacht habe und davor nur bisschen C# und Java ist das alles wieder recht mühsam.
Aber was tut man nicht alles für ein paar schnelle ECTS?

Bei der Aufgabe oben war halt nur die Main Funktion gegeben und man muss die passenden Klassen dazu schreiben. Wobei Membervariablen immer private sein müssen und man nur <iostream> verwenden darf und keine globalen Variablen.

Was ich mir in meinem "selbst C++ Crashkurs" erlesen hab ist, dass ich bei Funktionen const dann dazu geben kann, wenn ich weiss, dass ich dort keine Werte verändere. Aber ist das nicht was optionales und nicht was notwendiges?

Betragk war sicher ein Tippfehler, aber schätze ich mal erst beim kopieren passiert. Solche Fehler würden normal vom Compiler entdeckt werden und ich würds normal auch sehen :) .

Wie würde man eigentlich schön die Membervariablen bezeichnen? - Ich möchte ja auch was dazu lernen?

Gibt es hier einen Grund warum ich den BarWert nicht mit const deklariere oder einfach nur vergessen?

Code: Alles auswählen

ostream& operator<<(ostream& out, BarWert& bw){
	out<<bw.getWaehrung()<<" "<<bw.getWert();
	return out;
};
Roughael
Stripe
Stripe
Beiträge: 2498
Registriert: Mär 2002

Beitrag von Roughael »

meist ist const was optionales, aber in diesem beispiel:
ostream& operator<<(ostream& out, Konto& k)

musst du eine nicht const referenz übergeben.
Aus dem Konto() aufruf hier jedoch macht gcc ein konstantes objekt:
cout<<Konto(EUR,-500,1000)<<endl;

bin zu lange aus c++ raus um mich zu erinnern warum.
(anderherum schadet es aber sogut wie nie const einzusetzen)
Hättest du statt dessen eine echte variable übergeben hätte es funktioniert:

Konto konto(EUR,-500,1000);
cout<<konto<<endl;

Es hätte auch funktioniert wenn du keine Referenz als argument genommen hättest sondern eine lokale kopie:
ostream& operator<<(ostream& out, Konto k)

Aber parameter als kopie zu übergeben sollte man vermeiden. kostet unnötig leistung (ausnahme: Plain Old Data typen, also int, char, zeiger, etc.).

Benennung von Variablen:
camelCase (kleiner Anfangsbuchstabe und für jedes Wort einen großen Anfangsbuchstaben.
ungarische notation, prefixe (_, m_, etc.) sind dank guter Intellisense heutzutage nicht mehr notwendig.

>Gibt es hier einen Grund warum ich den BarWert nicht mit const deklariere oder einfach nur vergessen?
übersehen.
<-- Ehemaliger TTK-Bandit, bis inquake rumzickte -->

Dict.cc Firefox Addon | Q3Devel | Code3Arena(De) | GameType Revolution | Open Game Libraries
Antworten