getter-setter Problem

BLR

Erfahrenes Mitglied
Hallo Leute,

ich habe heute begonne mit Objektorintierung in C++ anzuschauen.
Dazu habe ich
1. Header-Datei: "Artikle_values" dort habe ich meine Methoden definiert (scheint mir so zu sein wie Interface in java)
2. .cpp Datei von "Artikle_values" habe ich implementiert, sodass der Compiler nicht mekert. Das Programm wird gestartet.
3. In der Main rufe ich das Programm auf.

Code:
Main: (auf was wesentlilche reduziert)


Code:
main (){
        vector<Artikle_values> week(6);
        //Drei Objekte erzeugen mit dem Konstruktor erzeugen.
        week.push_back(Name_Values("Ich"));
        week.push_back(Name_Values("Du"));
        week.push_back(Name_Values("Er")); 

        //Jedem Objekt 3 Zahlen zuweisen, die später abgefragt werden
       week.at(0).add_value(zahl);
       week.at(0).add_value(zahl);
       week.at(0).add_value(zahl);

       week.at(1).add_value(zahl);
       week.at(1).add_value(zahl);
       week.at(1).add_value(zahl);
     
       week.at(2).add_value(zahl);
       week.at(2).add_value(zahl);
       week.at(2).add_value(zahl);
    
     
}
Construktor in der Header-Datei, wo der Name während des "Push_back" landet
Da wo ich den Vector fülle, gehe ich in den Constructor rein, und die Membervariable wird gesetzt.

Header-Datei:

Code:
 Name_Values(string nameDay){
        name = nameDay;
    }

in der Main jeden Namen vom Vector<article_values> abfragen:
Code:
 //Namen abfragen:

       for (int i = 0; i < week.size() - 1; i++) {

             cout << week[0].get_name();
             // oder 
             cout << week.at(0).get_name();

        }


jetzt der cpp-getter.

Code:
string Name_Values::get_name() const {
    return name;
}

und der Inhalt von der "name" Variable im Return-Statment ist leer.
Was ist hier falsch****?
Danke für jeden Tipp.
 
Zuletzt bearbeitet:
Grundsätzlich ist die header-Idee in der C-Familie so gedacht: Im Header stehen nur Deklarationen (nichts, was Speicher reserviert). Die Definitionen zu den Deklarationen stehen in der *.cpp Datei.

Ein Beispiel:
Person.h
C++:
#ifndef PERSON_H_INCLUDED
#define PERSON_H_INCLUDED

#include <string>

class Person
{
    std::string name;
    int gewicht;

    public:
            Person (const std::string _name, int _gewicht);
            std::string getName();
            ~Person();
};

#endif // PERSON_H_INCLUDED

Person.cpp:
C++:
#include "Person.h"
#include <string>

using namespace std;

Person::Person (const string _name, int _gewicht)
{
    name = _name;
    gewicht = _gewicht;
}

string Person::getName()
{
    return name;
}

Person::~Person()
{

}

main.cpp:
C++:
#include "Person.h"
#include <iostream>

using namespace std;

int main()
{
    Person p ("Hans", 80);

    cout << p.getName() << endl;

    return 0;
}

Ich habe jetzt deinen Code nur überflogen und auf die Schnelle keinen Fehler gefunden. Baue es einmal um wie von mir beschrieben, vielleicht funktioniert es dann schon.

Lg
 
Zuletzt bearbeitet:
ok...habe ich jetzt gemacht.
Aber erst mal:
Was ist ne Definition****
Wenn deklaration doch ist: "int zahl;", wo ist den hier die Definition****

Jedenfalls bringt das leider nichts.
Mit dem getter, kriege ich den Namen nicht raus.

header:

Code:
class Artikle_Values {
public:
    Artikle_Values();
    Artikle_Values(string nameDay);
    Artikle_Values(string nameDay, vector<int> digitOfDay);

    Artikle_Values(const Name_Values& orig);
    virtual ~Artikle_Values();
    
    string get_name()const ;  
    
    vector<int> get_day() const;
   
    void add_value(int);
    

private:
    string name;
    vector<int> dayValue;
    
};

cpp. Datei:
Code:
Artikle_Values::Name_Values() {
}

Artikle_Values::Name_Values(string nameDay){
    name = nameDay;  //hier geht er rein, wenn ich meinen Code, was in der main steht, ausführe.
}

Artikle_Values::Name_Values(string nameDay, vector<int> digitOfDay){
    name = nameDay;
    dayValue = digitOfDay;
}

Artikle_Values::Name_Values(const Name_Values& orig) {

}

string Artikle_Values::get_name() const {
    return name; //hier kriegt er einen leeren String, wenn ich in der main, den getter aufrufe
}

main:

Code:
vector<Artikel_Values> week(6); //sieben objekte von Artikel_Values
week.push_back(Artikel_Values("test")); //einen erzeugen und er geht in den entsprechend Construktor rein
cout << week[0].get_name() // den namen "test" auf der Console ausgeben lassen funktioniert nicht

waaarum?
 
Zuletzt bearbeitet:
Eine Deklaration ist nur eine Bekanntgabe, das es etwas gibt. Bei einer Deklaration alleine wird aber noch KEIN Speicher reserviert!

Bei einer Definition wird dann der Speicher reserviert. ( -> jede Definition ist auch implizit eine Deklaration)

C++:
int a; // Definition
void a();  // Deklaration
extern int a; // Deklaration


Zu deinem Code: Du verwendest manchmal Artikle_values und manchmal Name_values. Die Konstruktoren usw. von Artikle_values sind in deinem geposteten Code nicht enthalten.

Lg
 
ahh vielen Dank für die Klarstellung.
ja, hab noch nach dem Test die Namen im Header verwendet, aber die alten Bennenungen in der cpp hier reingepostet. Habs jetzt angepasst. Also im Header und in der .cpp Datei heißt die Klasse Artikel_Values.

Der Code läuft auch soweit, d.h. er geht in den Construktor mit einem Argument rein.
Nur wenn ich dann das Objekt aus dem Vektor mit "at(0)" mit dem Getter abfrage, ist alles leer.

Wobei, wenn das Objekt an "at(0)" nicht da wäre, dann würde mir auch c++ wahrscheinlich sowas wie null-pointer werfen, was es nicht tut....
 
OK, ein trickreiches Problem ;)

Wenn du etwas dem vector hinzufügt, wird das Objekt kopiert und die Kopie in den vector eingefügt. Wenn ein Objekt kopiert wird, wird automatisch sein copy-Konstruktor aufgerufen. Normalerweise erstellt die Klasse selbst einen Copy-Konstruktor, der einfach die Attribute zuweist, nur hast du schon einen Copy-Konstruktor definiert der aber nichts macht. Das bedeutet die Klasse erstellt keinen mehr und dein copy-Konstruktor, der nichts macht, wird verwendet.

Der Copy-Konstruktor sollte so aussehen:
C++:
Artikle_Values::Name_Values(const Artikle_Values& orig) {
       name = orig.name;
       dayValue = orig.dayValue; 
}

Lg
 
Ähhmm....das mit dem Copy-Konstruktor ist sehr interessant :)
In der Tat, wenn ich von NetBeans eine c++ class-datei automatisch erstellen lasse, wird auch eine Header-Datei angelegt.

Ausser dem Argumentlosen Konstrukor wird auch so ein Construktor angelegt:

Code:
  Name_Values(const Name_Values& orig);

Jetzt scheint es mir, dass das der besagter Copy-Konstruktor ist....
Also wird automatisch ein normaler Konstruktor angelegt.
Dann ein Kopy-Konstruktor.

Wann wird jetzt welcher Konstruktor genau verwendet****?
Und kann ich c++ irgendwie zwingen den normalen zu verwenden und nicht den Copy-Konstruktor****?
 
Also eigentlich ist der Copy-Konstruktor nur ein ganz normaler Konstruktor, der als Argument immer eine konstante Referenz auf ein Objekt derselben Klasse bekommt.

Ein Beispiel:
C++:
class Person
{
        public:
                 Person (const Person &p);
};

Und noch einmal: er ist eigentlich nur ein ganz normaler Konstruktor.
Ein Beispielaufruf:

C++:
Person p;
Person p1 (p);

Der Copy-Konstruktor sollte einfach ein Objekt anhand eines anderen Objekts des selben Typs erstellen. Und weil man sich die Entwickler von C++ gedacht haben, dass so etwas immer möglich sein soll, wird der Copy-Konstruktor, wenn er von dir nicht deklariert wird, vom Compiler erstellt. Der vom Compiler erstellte Copy-Konstruktor macht eben nichts anderes, als die Attribute des neuen Objekts vom alten Objekt zu kopieren (wie der Code aus meinem letzten Post).

Der Hintergrund der ganzen Sache ist folgender: In C++ kann man Objekte an Funktionen ja byValue übergeben. Dabei werden die Objekte ja kopiert und auf den Stack gelegt. Genau hier kommt der Copy-Konstruktor zum Einsatz. In Java wird der Copy-Konstruktor nicht automatisch erstellt, weil dort alles über callByReference passiert, da braucht man dann keinen Copy-Konstruktor.

Beim vector hast du jetzt folgendes Problem: Wenn du push_back() aufrufst, wird ein neues Objekt vom übergebenen erstellt (Copy-Konstruktor!) und das dann in den vector eingefügt. Das war bei dir das Problem.

Lg
 
Zurück