Funktion soll andere Funktion aufrufen
-
Schreibe ein Programm das ein Gesicht zeichnen soll. Dazu habe ich zwei klassen (Smiley, und Frowny das bald folgen wird) von der klasse Cricle abgeleitet. Da die Klasse Smiley ja von Circle alles erbet wurde auf einen Konstrutkor verzichtet. Statt dessen habe ich die draw_lines() Funktion überschrieben da diese in der hauptklasse eine Virtuelle Funktion ist. Das ist kein Problem, nur was ich nicht hinbekomme ist wie mache ich das die Funktion f() die draw_lines() von Smiley aufruft und nicht den draw_lines() Funktion in der geerbten klasse. Es geht darum ich will das es kein Kreis gezeichnet werden soll sondern nur ein Teil des Kreises.
Outline.h:
#include "Graph.h" #include "Point.h" #include "std_lib_facilities.h" struct Smiley:Circle { void draw_lines() const; private: int rr; }; void Smiley::draw_lines() const // diese funktion zeichent nur ein teil des Kreises { if (color().visibility()) fl_arc(point(0).x,point(0).y,rr+rr,rr+rr,0,180); // 360 ist der ganze kreis, das ist die hälfte }#include "Graph.h" #include "GUI.h" #include "Point.h" #include "Simple_window.h" #include "std_lib_facilities.h" #include "Window.h" #include "Outline.h" void f(const Circle& s) // es will kein Smiley objekt annehmen { s:Smiley.draw_lines(); // wie rufet man hier die Smiley draw_lines() funktion auf? } int main() { using namespace Graph_lib; Point tl(100,100); Simple_window win1(tl,600,400,"Face"); Circle s1(Point(250,170),150); // zeichnet kreise Circle s2(Point(170,150),30); Circle s3(Point(330,150),30); Smiley:Circle s4(Point(210,220),90); f(s4); win1.attach(s1); win1.attach(s2); win1.attach(s3); win1.attach(s4); win1.wait_for_button(); }
-
Warum ":"? Einfach s.draw_lines(). Hast ja bereits das Objekt, außerdem kannst du nicht über eine Revererbung ohne Definition vornehmen.
-
Wenn draw_lines virtuell ist und du ein Smiley-Objekt übergibst, wird automatisch die Funktion von Smiley genommen. Die Vererbung ist strittig, da es fraglich ist, ob ein Smiley ein Kreis ist oder nur kreisförmig ist.
-
Kóyaánasqatsi schrieb:
Warum ":"? Einfach s.draw_lines(). Hast ja bereits das Objekt, außerdem kannst du nicht über eine Revererbung ohne Definition vornehmen.
Wenn ich das so mache das ich s.draw_lines() aufrufe wird dann die Funktion der Hauptklasse aufgerufen und es wird ein ganzer Kreis gezeichnet. Aber ich will nur ein Teil des Kreises zeichnen, das soll dann ein Lächeln werden. Aber wie macht man Revererbung mit Definition, oder sollte ich das Design überdenken?
-
Eine Änderung:
void f(const Smiley& s) { s.draw_lines(); } int main() { using namespace Graph_lib; Point tl(100,100); Simple_window win1(tl,600,400,"Face"); Circle s1(Point(250,170),150); // zeichnet kreise Circle s2(Point(170,150),30); Circle s3(Point(330,150),30); Smiley:Circle s4(Point(210,220),90); f(s4); // Fehler 9 und 8 win1.attach(s1); win1.attach(s2); win1.attach(s3); win1.attach(s4); win1.wait_for_button(); }Die Fehler:
Fehler 9 IntelliSense: Es ist keine passende benutzerdefinierte Konvertierung von " "Graph_lib::Circle"" in ""const Smiley"" vorhanden.
Fehler 8 error C2664: 'f': Konvertierung des Parameters 1 von 'Graph_lib::Circle' in 'const Smiley &' nicht möglich
-
@winux: Was soll denn die Zeile
Smiley:Circle s4(Point(210,220),90);? Du setzt ein Label Smiley und definierst dann das Objekt s4 vom Typ Circle. Kein Wunder, dass ein Kreis gezeichnet wird, wenn du einen erstellst.
-
wxSkip schrieb:
@winux: Was soll denn die Zeile
Smiley:Circle s4(Point(210,220),90);? Du setzt ein Label Smiley und definierst dann das Objekt s4 vom Typ Circle. Kein Wunder, dass ein Kreis gezeichnet wird, wenn du einen erstellst.Richtig, aber wenn ich das Smiley:Circle weglasse dan sagt der Compiler:
9 IntelliSense: Keine Instanz des Konstruktors ""Smiley::Smiley"" stimmt mit der Argumentliste überein.
Fehler 8 error C2660: 'Smiley::Smiley': Funktion akzeptiert keine 2 Argumente
-
Kannst du uns mal den Konstruktor von Circle zeigen? Anscheinend gibt es ja keinen derartigen Konstruktor von Smiley.
-
wxSkip schrieb:
Kannst du uns mal den Konstruktor von Circle zeigen? Anscheinend gibt es ja keinen derartigen Konstruktor von Smiley.
Ja:
struct Circle : Shape { Circle(Point p, int rr); // center and radius void draw_lines() const; Point center() const ; int radius() const { return r; } void set_radius(int rr) { r=rr; } private: int r; };Wenn ich denn gleichen Konstrutor definiere dann gibt es keine Fehler nur das Programm läst sich nicht Compilieren und ausführen.
Fehler 9 error LNK2001: Nicht aufgelöstes externes Symbol ""public: __thiscall Smiley::Smiley(struct Point,int,int)" (??0Smiley@@QAE@UPoint@@HH@Z)".
Fehler 10 error LNK1120: 1 nicht aufgelöste externe Verweise.
-
winux schrieb:
Wenn ich denn gleichen Konstrutor definiere dann gibt es keine Fehler nur das Programm läst sich nicht Compilieren und ausführen.
Das ist ein Paradoxon. Versuch mal einen Konstruktor zu machen, der einfach den Konstruktor von Circle aufruft.
EDIT: Du hast den Konstruktor nur deklariert, nicht definiert oder jedenfalls nicht gelinkt.
-
wxSkip schrieb:
winux schrieb:
Wenn ich denn gleichen Konstrutor definiere dann gibt es keine Fehler nur das Programm läst sich nicht Compilieren und ausführen.
Das ist ein Paradoxon. Versuch mal einen Konstruktor zu machen, der einfach den Konstruktor von Circle aufruft.
EDIT: Du hast den Konstruktor nur deklariert, nicht definiert oder jedenfalls nicht gelinkt.
So etwas? Smiley::Circle;
-
winux schrieb:
wxSkip schrieb:
winux schrieb:
Wenn ich denn gleichen Konstrutor definiere dann gibt es keine Fehler nur das Programm läst sich nicht Compilieren und ausführen.
Das ist ein Paradoxon. Versuch mal einen Konstruktor zu machen, der einfach den Konstruktor von Circle aufruft.
EDIT: Du hast den Konstruktor nur deklariert, nicht definiert oder jedenfalls nicht gelinkt.
So etwas? Smiley::Circle;
Nein.
Smiley::Smiley(Point p, int rr) : Circle(p, rr) { }
-
wxSkip schrieb:
winux schrieb:
wxSkip schrieb:
winux schrieb:
Wenn ich denn gleichen Konstrutor definiere dann gibt es keine Fehler nur das Programm läst sich nicht Compilieren und ausführen.
Das ist ein Paradoxon. Versuch mal einen Konstruktor zu machen, der einfach den Konstruktor von Circle aufruft.
EDIT: Du hast den Konstruktor nur deklariert, nicht definiert oder jedenfalls nicht gelinkt.
So etwas? Smiley::Circle;
Nein.
Smiley::Smiley(Point p, int rr) : Circle(p, rr) { }Danke das wahr eine große Hilfe.
Die Änderung in der Header:
struct Smiley:Circle { Smiley::Smiley(Point p, int r) : Circle(p, r) { add(Point(p.x-r,p.y-r)); } void draw_lines() const; private: int r; }; void Smiley::draw_lines() const { if (color().visibility()) fl_arc(point(0).x,point(0).y,r+r,r+r,0,360); }
-
Das Smiley:: kannst du innerhalb der Klassendefinition weglassen. Schreib deine Funktionen lieber in eine Sourcedatei.
-
Jetzt aber gibt es folgendes Problem der Kreis wird nicht gezeichent.
Habe dies Änderungen gemacht.
Outline.hstruct Smiley:Circle { Smiley(Point p, int r) : Circle(p, r) { add(Point(p.x-r,p.y-r)); } void draw_lines() const; Point center() const { return Point(point(0).x+r, point(0).y+r); } int radius() const { return r; } void set_radius(int rr) { r=rr; } private: int r; }; void Smiley::draw_lines() const { if (color().visibility()) fl_arc(point(0).x,point(0).y,r+r,r+r,0,360); }Die Deklaration und Definition von Circle:
struct Circle : Shape { Circle(Point p, int rr); // center and radius void draw_lines() const; Point center() const ; int radius() const { return r; } void set_radius(int rr) { r=rr; } private: int r; };Circle::Circle(Point p, int rr) // center and radius :r(rr) { add(Point(p.x-r,p.y-r)); // store top-left corner } //------------------------------------------------------------------------------ Point Circle::center() const { return Point(point(0).x+r, point(0).y+r); } //------------------------------------------------------------------------------ void Circle::draw_lines() const { if (color().visibility()) fl_arc(point(0).x,point(0).y,r+r,r+r,0,360); }
-
Hm... ich nehme an, der Mund wird gezeichnet, aber der Kreis nicht. Du solltest in diesem Fall Circle::draw_lines() in deine Shape::draw_lines()-Funktion einfügen.
-
wxSkip schrieb:
Hm... ich nehme an, der Mund wird gezeichnet, aber der Kreis nicht. Du solltest in diesem Fall Circle::draw_lines() in deine Shape::draw_lines()-Funktion einfügen.
Alles wird gezeichnet nur wenn ich Smiley wird nicht gezeichnet, die Circle Objekte schon. Also Kopf und die zwei Augen werden gezeichnet, aber der Mund nicht.
-
Ist die Lösung nicht das?
Circle::Circle(Point p, int rr) // center and radius :r(rr) // dieses Initialisierung { add(Point(p.x-r,p.y-r)); // store top-left corner }
-
winux schrieb:
wxSkip schrieb:
Hm... ich nehme an, der Mund wird gezeichnet, aber der Kreis nicht. Du solltest in diesem Fall Circle::draw_lines() in deine Shape::draw_lines()-Funktion einfügen.
Alles wird gezeichnet nur wenn ich Smiley wird nicht gezeichnet, die Circle Objekte schon. Also Kopf und die zwei Augen werden gezeichnet, aber der Mund nicht.
Wo soll der Mund denn herkommen? Beide draw_lines()-Funktionen sehen genau gleich aus.
-
wxSkip schrieb:
winux schrieb:
wxSkip schrieb:
Hm... ich nehme an, der Mund wird gezeichnet, aber der Kreis nicht. Du solltest in diesem Fall Circle::draw_lines() in deine Shape::draw_lines()-Funktion einfügen.
Alles wird gezeichnet nur wenn ich Smiley wird nicht gezeichnet, die Circle Objekte schon. Also Kopf und die zwei Augen werden gezeichnet, aber der Mund nicht.
Wo soll der Mund denn herkommen? Beide draw_lines()-Funktionen sehen genau gleich aus.
OK, da habe ich ein Fehler gemacht. Habe jetzt Smiley draw_lines() geändert. Auch wenn ich s4.draw_lines() aufrufe wird nichts gezeichnet.