Schwierigkeiten beim Klasse vererben
-
Sobald Du mit eigenen Ableitungen arbeitest, musst Du die Deklaration (h-Datei) und Implementierung (cpp-Datei) trennen, da es sonst zu solchen Problemen kommt... da ist C# etwas besser
-
Könntest du mir das an meinem Code demonstrieren? Die sind doch getrennt - was soll ich anders machen? Irgendwie muss ich die Funktionen doch bekannt geben ... oder verstehe ich hier etwas falsch?
Meinst du die beiden Konstruktoren? Sollen die in die cpp?
-
Lass mal das mit den Funktionen. Deine Basis Klasse ist unbekannt, das ist das erste Problem, welches Du lösen musst.
Simon
-
Ihr wisst ja , ich bin auch jetzt noch Anfänger. Diese Fehler sind doch abhängig von der Forms Klasse ...
Fehler 9 error C2039: 'Padding': Ist kein Element von 'Kinder::sidebarfolder' c:\users\jan\documents\visual studio 2008\projects\kinder\kinder\sidebarfolder.h 61 Fehler 6 error C2039: 'Size': Ist kein Element von 'Kinder::sidebarfolder' c:\users\jan\documents\visual studio 2008\projects\kinder\kinder\sidebarfolder.h 59 Fehler 7 error C2872: 'Text': Mehrdeutiges Symbol c:\users\jan\documents\visual studio 2008\projects\kinder\kinder\sidebarfolder.h 60 Fehler 8 error C2882: 'Text': Unzulässige Verwendung eines Namespace-Bezeichners in einem Ausdruck c:\users\jan\documents\visual studio 2008\projects\kinder\kinder\sidebarfolder.h 60
... oder nicht?
Es gibt doch Möglichkeiten, auf mehrere Klassen zu verweisen ?! Wie würde das aussehen?
Habe die Klasse einmal neu erstellt, unter dem Namen FolderSidebar. Dann habe ich sie wie gehabt so bearbeitet:
public ref class FolderSidebar : public Kinder::panelklasse
Im Designer wird die Form wie in der Panelklasse eingerichtet - angezeigt. Sobald ich aber SidebarFolder in die Sidebar.h include - entstehen die euch bekannten Fehler.
Also kommen wir dem Fehler langsam nahe?
-
Was steht in Sidebar.h?
-
#pragma once #include "registryhilfe.h" #include "Form1.h" #include "panelklasse.h" #include "pingpanel.h" #include "FolderSidebar.h" namespace Kinder { ref class Form1; ref class FolderSidebar; ref class panelklasse; public ref class Sidebar : public System::Windows::Forms::Form { public: static emailpanel ^emailpanelinstanz; static Form1 ^form1instanz; static systeminfo ^systeminfoinstanz; static hddinfo ^hddinfoinstanz; static ipinfopanel ^ipinfopanelinstanz; static pingpanel ^pingpanelinstanz; void bildschirmauflösung (); void emailwächterstarten (); void minidesktopanzeigen (); void soundanaus (); void effekte (System::String^); void sichtbarkeit (int); void einstellungen (); void beenden (); void formaktualisieren (); void sidebarandocken (); void sidebarimhintergrund (); void sidebarimvordergrund (); void sonstigeeinstellungen (); void speichern (); void workareastandard (); BOOL SetResolution(int width,int height,int bpp); void fensterminimieren (); void systeminfo (); void systeminfobeenden (); void hddinfobeenden (); void hddinfo (); void hddinterval (int); void emailinfobeenden (); void emailpanelanzeigen (); void ipinfopanelbeenden (); void ipinfopanelanzeigen (); void pingpanelbeenden (); void pingpanelanzeigen (); void pinginterval (int); Sidebar(void) { InitializeComponent(); bildschirmauflösung (); } Sidebar(Form1 ^form) { form1instanz = form; InitializeComponent(); workareastandard (); bildschirmauflösung (); formaktualisieren (); sonstigeeinstellungen (); } protected: ~Sidebar() { if (components) { delete components; } }
-
Du hast zirkuläre Abhängigkeiten der Klassen, bzw. Header!
Ich habe auch bemerkt, dass Du meistens Vorwärtsdeklarationen UND includes machst.
Mache wenn möglich Vorwärtsdekl. und sonst inlcudes.
Ich mach noch kurz ein Bsp:
Panel.h
ref class Sidebar; // Vorwärtsdeklaration ref class Panel { public: Panel(Sidebar^ sidebar); private: Sidebar^ sidebar; };
Panel.cpp
#include "stdafx.h" #include "Panel.h" #include "Sidebar.h" // hier wird die Definition benötigt! Panel::Panel(Sidebar^ sidebar) { this->sidebar = sidebar; }
Sidebar.h
ref class Panel; // Vorwärtsdeklaration ref class Sidebar { public: void SetPanel(Panel^ panel); private: Panel^ panel; };
Sidebar.cpp
#include "stdafx.h" #include "Sidebar.h" #include "Panel.h" // hier wird die Definition benötigt! Sidebar::SetPanel(Panel^ panel) { this->panel = panel; }
-
Bin immer dankbar für solche Tipps - wenn nicht von euch - von wem dann? Das heißt also Includes ODER Vorwärtsdeklaration - nicht beides zusammen ?
-
shaun1981 schrieb:
Das heißt also Includes ODER Vorwärtsdeklaration - nicht beides zusammen ?
Eigentlich eher so:
a.) Entweder Im Header File die Vorwärtsdekl. und im Source File das Inklude.ODER
b.) Gerade im Header File das Inklude
Wobei a.) vorzuziehen ist, denn es verkleinert die Abhängigkeiten.
Informiere dich doch zum Thema Deklaration und Definition.
Simon
-
Danke dir. Das mache ich nochmal .. manches überliest man wohl einfach. Dein Lösungsvorschlag funktioniert nun - und ich verstehe ihn diesmal auch
Wobei nun noch ein kleines Problem zu beheben wäre. Wenn ich nun aus der abgeleiteten FolderSidebar Klasse heraus bspw. die Funktion SIDEBARPOSITION der Basisklasse aufrufe, und diese ja so aussieht:
void Kinder::panelklasse::sidebarposition () { System::Drawing::Point loc = System::Drawing::Point (sidebarinstanz->Location.X, sidebarinstanz->Location.Y + 500); this->BackgroundImage = sidebarinstanz->BackgroundImage; this->BackColor = sidebarinstanz->BackColor; this->Location = loc; this->Invalidate (); }
... bezieht sich der this Zeiger ja nicht auf die von mir gewünschte Form - sondern auf die Panelklasse. Was würde ich hier am besten übergeben?
Eigentlich könnte ich ja den this Zeiger übergeben. Nur stellt sich mir die Frage, wie ich in der Basis Klasse die Funktion SIDEBARPOSITION definiere. Ich meine da sich <this> ja bei allen neuen Panels ändert, kann ich ja nun nicht eine Variable vom Typ FolderSidebar erstellen, was hier natürlich funktionieren würde, nur beim nächsten Panel XYZ würde es doch da zu Problemen kommen - oder ?
-
So hab ich es versucht:
public: void sidebarposition (System::Windows::Forms::Form^);
void Kinder::panelklasse::sidebarposition (System::Windows::Forms::Form^ sender) { System::Drawing::Point loc = System::Drawing::Point (sidebarinstanz->Location.X, sidebarinstanz->Location.Y + 500); String^ hilfe = sender->ToString (); sender->BackgroundImage = sidebarinstanz->BackgroundImage; sender->BackColor = sidebarinstanz->BackColor; sender->Location = loc; sender->Invalidate (); /* this->BackgroundImage = sidebarinstanz->BackgroundImage; this->BackColor = sidebarinstanz->BackColor; this->Location = loc; this->Invalidate (); */ }
...aufgerufen so:
FolderSidebar(Sidebar^ instanz) { sidebarinstanz = instanz; InitializeComponent(); sidebarposition (this); größeanpassen (); überschriftändern ("Sidebar Folder"); this->Show (); }
Fehler gibts keine, jedoch wird das Panel FolderSidebar nicht an der vorgesehenen Position angezeigt.
-
Also folgendes, falls noch jemand lust hat , einen Blick darauf zu werfen
Starte ich die ganze Sache, wird das Folder Sidebar Panel an irgendeiner Position - so scheint es zumindest - angezeigt. Allerdings habe ich ja in der Basisklasse eine Funktion die das Panel ab bzw. andocken soll - und funktioniert auch.
Wenn ich das Panel nun abdocke - und es dadurch einen Rahmen (FormBorderStyle) bekommt, und es anschliessend wieder andocke, wird es wie gewollt in der Sidebarposition festgelegten Position angezeigt.
Hier mal der aktuelle Code:
panelklasse.h
#pragma once using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; namespace Kinder { ref class Sidebar; public ref class panelklasse : public System::Windows::Forms::Form { public: panelklasse () { InitializeComponent (); } public: panelklasse (Sidebar^ instanz) { instanz = sidebarinstanz; } protected: ~panelklasse() { if (components) { delete components; } } public: Sidebar ^sidebarinstanz; public: void sidebarposition (System::Windows::Forms::Form^); public: void größeanpassen (); public: void beenden (); public: void schriftfarbeändern (); public: void überschriftändern (System::String^); ... ... ... private: System::Void abdockenToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) { this->FormBorderStyle = ::FormBorderStyle::FixedToolWindow; this->TopMost = false; this->Invalidate (); contextMenuStrip1->Items[3]->Enabled = false; contextMenuStrip1->Items[4]->Enabled = true; contextMenuStrip1->Refresh (); } private: System::Void andockenToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) { this->Visible = false; this->Refresh (); this->FormBorderStyle = ::FormBorderStyle::None; this->TopMost = true; contextMenuStrip1->Items[3]->Enabled = true; contextMenuStrip1->Items[4]->Enabled = false; contextMenuStrip1->Refresh (); sidebarposition (this); this->Invalidate (); this->Visible = true; }
panelklasse.cpp
#include "StdAfx.h" #include "panelklasse.h" #include "Sidebar.h" void Kinder::panelklasse::sidebarposition (System::Windows::Forms::Form^ sender) { System::Drawing::Point loc = System::Drawing::Point (sidebarinstanz->Location.X, sidebarinstanz->Location.Y + 500); String^ hilfe = sender->ToString (); sender->BackgroundImage = sidebarinstanz->BackgroundImage; sender->BackColor = sidebarinstanz->BackColor; sender->Location = loc; sender->Invalidate (); }
FolderSidebar.h
#pragma once #include "Sidebar.h" #include "panelklasse.h" using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; namespace Kinder { ref class panelklasse; public ref class FolderSidebar : public Kinder::panelklasse { ref class System::Windows::Forms::Form; public: ... FolderSidebar(Sidebar^ instanz) { sidebarinstanz = instanz; InitializeComponent(); sidebarposition (this); größeanpassen (); überschriftändern ("Sidebar Folder"); this->Invalidate (); this->Show (); } ... ...
-
*schäm*
Vielleicht sollte ich die Start Position Eigenschaft auf Manuel umstellen.
Danke euch nochmal für die schnelle Hilfe weiter oben.