Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Problem mit Konstruktor

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ] [ 3 ]
000
28.11.2015, 16:44 Uhr
Yadgar



Hi(gh)!

Die Klasse sieht so aus:


C++:
class pixel
{
  public:
    pixel (unsigned char, unsigned char, unsigned char); // Konstruktor
    ~pixel(); // Destruktor
    void set_all(int, int, int);
    void set_red(int);
    void set_green(int);
    void set_blue(int);
    unsigned char* get_all();
    unsigned char get_red();
    unsigned char get_green();
    unsigned char get_blue();
    void invert();
  private:
    unsigned char r;
    unsigned char g;
    unsigned char b;
};

void pixel::set_all(int red, int green, int blue)
{
  r = (unsigned char)red;
  g = (unsigned char)green;
  b = (unsigned char)blue;
}

void pixel::set_red(int red)
{
  r = (unsigned char)red;
}

void pixel::set_green(int green)
{
  g = (unsigned char)green;
}

void pixel::set_blue(int blue)
{
  b = (unsigned char)blue;
}

unsigned char* pixel::get_all()
{
  unsigned char colvals[] = { r, g, b };
  return colvals;
}

unsigned char pixel::get_red()
{
  return r;
}

unsigned char pixel::get_green()
{
  return g;
}

unsigned char pixel::get_blue()
{
  return b;
}

void pixel::invert()
{
  r = 255-r;
  g = 255-g;
  b = 255-b;
}



Ein kleines Testprogramm:


C++:
#include <iostream>
#include <vector>;
#include "yip_classes.h";
using namespace std;

int main()
{
  pixel p1((unsigned char)255, (unsigned char)0, (unsigned char)0);
  pixel p2(0, 255, 0);
  pixel p3(0, 0, 255);

  unsigned char* triple = p1.get_all();
  cout << "Pixel object p1" << endl;
  cout << "Red:   " << (int)triple[0] << endl;
  cout << "Green: " << (int)triple[1] << endl;
  cout << "Blue:  " << (int)triple[2] << endl;
  cout << endl;

  return 0;
}



Als Fehlermeldung bekomme ich (unter anderem) das hier:

yip_classes_test.cc.text+0x147): undefined reference to `pixel::pixel(unsigned char, unsigned char, unsigned char)'
yip_classes_test.cc.text+0x162): undefined reference to `pixel::pixel(unsigned char, unsigned char, unsigned char)'
yip_classes_test.cc.text+0x17d): undefined reference to `pixel::pixel(unsigned char, unsigned char, unsigned char)'

Was habe ich bei der Deklaration/Definition des Konstruktors falsch gemacht?

Bis bald im Khyberspace!

Yadgar
--
Flagmaker - ein Programmier-Blog
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
28.11.2015, 17:32 Uhr
Yadgar



Hi(gh)!

Ich habe nochmal in einem Tutorial nachgesehen - explizite Konstruktoren und Destruktoren müssen wohl tatsächlich nach der Klassendefinition mit dem Scope-Operator definiert werden (oder halt inline)... danach wurde das Programm auch problemlos kompiliert.

Jetzt aber ein neues Problem: pixel::get_all() gibt ein Array mit den drei Farbwerten des jeweiligen Pixel-Objekts zurück:


C++:
unsigned char* pixel::get_all()
{
  unsigned char colvals[] = { r, g, b };
  return colvals;
}



aber obwohl ich p1 mit (255, 0, 0) initialisiert habe, bekomme ich beim Aufruf von p1.get_all() nur 0, 0, 0:


C++:
  unsigned char* triple = p1.get_all();
  cout << "Pixel object p1" << endl;
  cout << "Red:   " << (int)triple[0] << endl;
  cout << "Green: " << (int)triple[1] << endl;
  cout << "Blue:  " << (int)triple[2] << endl;
  cout << endl;



Hätte ich besser p1.get_all()[0] usw. schreiben sollen?

Bis bald im Khyberspace!

Yadgar
--
Flagmaker - ein Programmier-Blog

Dieser Post wurde am 28.11.2015 um 17:46 Uhr von Yadgar editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
28.11.2015, 17:44 Uhr
ao

(Operator)


Du hast ihn zwar deklariert (d.h. den Funktionskopf hingeschrieben), aber nicht definiert (also keinen Code dafür geschrieben. Gleiches gilt für den Destruktor. Wobei es hier bisher nichts zu zerstören gibt. Es fehlt also folgendes:

pixel::pixel (unsigned char red, unsigned char green, unsigned char blue)
: r (red), g (green), b (blue)
{
}

pixel::~pixel() {}

Aber noch was viel wichtigeres: Die get_all-Methode ist so nicht brauchbar. Die gibt einen Zeiger auf ein lokales Objekt zurück, das ist ganz böse. Das funktioniert auf "kurze Strecken", solange der alte Speicherinhalt noch existiert.

Aber ruf mal zwischen get_all und den cout-Ausgaben irgendwelche anderen Funktionen auf, völlig egal, was, mach ein memcpy auf beliebigen Speicherbereichen oder hol dir die Uhrzeit. Stimmts dann immer noch?

Alternative für get_all: Definier dir ein struct rgb { unsigned char red, green, blue; } und benutz das als Rückgabetyp.

edit: da hat sich was überschnitten. Du hast es gerade selbst gemerkt.

Dieser Post wurde am 28.11.2015 um 17:45 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
28.11.2015, 17:50 Uhr
Yadgar



Hi(gh)!


Zitat von ao:

Aber noch was viel wichtigeres: Die get_all-Methode ist so nicht brauchbar. Die gibt einen Zeiger auf ein lokales Objekt zurück, das ist ganz böse. Das funktioniert auf "kurze Strecken", solange der alte Speicherinhalt noch existiert.



Ja, deswegen hat es auch eine Warnmeldung gegeben...


Zitat von ao:

Alternative für get_all: Definier dir ein struct rgb { unsigned char red, green, blue; } und benutz das als Rückgabetyp.



Global? Oder in main()?


Zitat von ao:

edit: da hat sich was überschnitten. Du hast es gerade selbst gemerkt.


Das erklärt es natürlich... habe längere Zeit nicht mehr programmiert, ich merke es!
Eigentlich sollte man jeden Tag drei bis sechs Stunden mit C++ verbringen, um wirklich gut zu werden...

Bis bald im Khyberspace!

Yadgar
--
Flagmaker - ein Programmier-Blog
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
28.11.2015, 18:42 Uhr
ao

(Operator)



Zitat von Yadgar:
[quote ao]
Alternative für get_all: Definier dir ein struct rgb { unsigned char red, green, blue; } und benutz das als Rückgabetyp.


Global? Oder in main()?
[/quote]
Einen RGB-Typ brauchst du an allen Ecken, wenn du Bildverarbeitung programmierst. Der kann ruhig global sein.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
28.11.2015, 18:49 Uhr
Yadgar



Hi(gh)!

Mittlerweile habe ich es raus:


C++:
struct rgb // global!
{
  unsigned char red;
  unsigned char green;
  unsigned char blue;
};


class pixel
{
  public:
    pixel (int, int, int); // Konstruktor
    ~pixel(); // Destruktor
    void set_all(int, int, int);
    void set_red(int);
    void set_green(int);
    void set_blue(int);
    void get_all(rgb&);
    unsigned char get_red();
    unsigned char get_green();
    unsigned char get_blue();
    void invert();
  private:
    unsigned char r;
    unsigned char g;
    unsigned char b;
};

void pixel::get_all(rgb &triple)
{
  triple.red = r;
  triple.green = g;
  triple.blue = b;
}



Und hier der Aufruf:


C++:
#include <iostream>
#include <vector>
#include "yip_classes.h"
using namespace std;


int main()
{
  pixel p1(255, 0, 0);
  pixel p2(0, 255, 0);
  pixel p3(0, 0, 255);


  rgb triple;

  p1.get_all(triple);
  cout << "Pixel object p1" << endl;
  cout << "Red:   " << (int)triple.red << endl;
  cout << "Green: " << (int)triple.green << endl;
  cout << "Blue:  " << (int)triple.blue << endl;
  cout << endl;

  return 0;
}



Danke für den Tipp, ao!

Bis bald im Khyberspace!

Yadgar
--
Flagmaker - ein Programmier-Blog
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
30.11.2015, 07:52 Uhr
ao

(Operator)


Du kannst eine Struktur auch als Rückgabewert verwenden:


C++:
rgb pixel::getall () const
{
    rgb result = { r, g, b };
    return rgb;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
12.01.2018, 12:33 Uhr
Sandra39



Hallo,

ich habe das gleiche Problem und finde den Fehler einfach nicht. Meine Fehlermeldung: undefined reference to Environment::Environment.
Vielleicht kann mir hier auch irgendwer helfen. Danke!

MFG

main.cpp


C++:
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include "environment.h"

using namespace std;
class Environment;

int main(int argc, char *argv[]) {

    int choice;
    int height, width;
    int h = 0;
    int w = 0 ;
    //Environment c;
    //Environment d;

    while(1) {
        cout <<endl;
        cout << "*********************************************************" <<endl;
        cout << "*\t\t\t\t\t\t\t*" <<endl;
        cout << "*\t\t\t\t\t\t\t*" <<endl;
        cout << "*\t\tAuthor: Sandra Priller\t\t\t*" <<endl;
        cout << "*\t\t\t\t\t\t\t*" <<endl;
        cout << "*\t\t\t\t\t\t\t*" <<endl;
        cout << "*********************************************************" <<endl;
        cout <<endl;
        cout << "\t\tAmeisensimulation - Spiel beginnen" <<endl;
        cout <<endl;

        cout << "1. Spielfeld erstellen >" <<endl;
        cout << "2. Koordinaten ausgeben >" <<endl;
        cout << "3. Items ausgeben >" <<endl;
        cout << "4. Spiel verlassen >" <<endl;
        cin >>choice;
        cout <<endl;


        switch(choice) {
            case 1:
                cout << "Geben Sie die Breite des Spielfelds ein [<=10]:" <<endl;
                cin >>width;
                cout <<endl;
                cout << "Geben Sie die Hoehe des Spielfeldes ein [<=10]:" <<endl;
                cin >>height;
                cout <<endl;

                if(height > 10) {
                    cout << "Die Hoehenangabe ist zu gross!" <<endl;
                    break;
                }
                else if(width > 10) {
                    cout << "Die Breitenangabe ist zu gross!" <<endl;
                }
                else {
                    //c.create_environment(h, w);
                    cout << "Das Spielfeld wurde erstellt und hat die Groesse " <<height<< " * " <<width<<endl;
                    break;
                }
            case 2:
                //d.display_coordinates(height, width);
                break;
            case 3:
                break;
            case 4:
                exit(0);
                break;
            default:
                cout << "Falsche Eingabe!" <<endl;
            }
    }

    return EXIT_SUCCESS;
}



environment.h


C++:
#define ENVIRONMENT_H_INCLUDED
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <math.h>

using namespace std;
class Area;

class Environment {
    public:
        Area *firstArea;
        int width;
        int height;

        Environment();

        ~Environment() {
        }

        create_environment(int h, int w);
        void display_coordinates(int height, int width);

};


#endif // ENVIRONMENT_H_INCLUDED



environment.cpp


C++:
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include "environment.h"


using namespace std;

Environment::create_environment(int h, int w) {
    Environment *myenv, *start = 0, *next, *prev;

    myenv = new Environment();
    myenv->height = h;
    myenv->width = w;
    myenv->next = NULL;

    cout << "Success!" <<endl;

    if(start == NULL) {
        myenv->prev = NULL;
        start = myenv;
    }
}
}

void Environment::display_coordinates(int height, int width) {
    int matrix[10][10] = {{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, 26, 27, 28, 29, 30},
                         {31, 32, 33, 34, 35, 36, 37, 38, 39, 40},
                         {41, 42, 43, 44, 45, 46, 47, 48, 49, 50},
                         {51, 52, 53, 54, 55, 56, 57, 58, 59, 60},
                         {61, 62, 63, 64, 65, 66, 67, 68, 69, 70},
                         {71, 72, 73, 74, 75, 76, 77, 78, 79, 80},
                         {81, 82, 83, 84, 85, 86, 87, 88, 89, 90},
                         {91, 92, 93, 94, 95, 96, 97, 98, 99, 100}};

    int i, j;

    for(i = 0; i < height; i++) {
        for(j = 0; j < width; j++) {
           printf("%4d", matrix[i][j]);
        }
        printf("\n");
    }
}


Dieser Post wurde am 12.01.2018 um 14:43 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
12.01.2018, 15:12 Uhr
ao

(Operator)



Zitat von Sandra39:
ich habe das gleiche Problem ...

... weil du den gleichen Fehler gemacht hast. Schreib folgendes in die environment.cpp:

Environment::Environment ()
{
}

Aber da sind noch einige weitere Fehler, und eigentlich dürftest du gar nicht bis "undefined reference" kommen, weil du vorher wegen anderer Fehler gestoppt wirst. Bist du sicher, dass das der aktuelle Codestand ist?

Und du hast ein paar grundlegende strukturelle Fehler gemacht bei dem Programm. Ist das eine Hausaufgabe, oder denkst du dir das gerade selber aus? Davon hängts ab, wie man dir am besten helfen kann.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
12.01.2018, 16:15 Uhr
Sandra39



Danke!

Ja das ist der momentane Codestand! Selber ausgedacht habe ich mir das jetzt nicht. Es soll eine Ameisensimulation werden, so ungefähr wie AntMe! bei der der Spieler die Spielfeldgröße selber bestimmen kann.

Vielen Dank für Deine Hilfe!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ] [ 3 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: