Frage zur Vererbung
-
Also ich habe eine Klasse A, die ich in Header und Source aufgeteilt habe. Ich möchte nun von ihrem Header eine Klasse B ableiten. Nun sind aber die Methoden der Wurzelklasse A in der Source-Datei von A implementiert.
Wie löse ich dieses Problem? Muss ich sie einfach in den Source von B kopieren oder geht das irgendwie eleganter?
-
Was spielt es für B eine Rolle, wo die Implementierung von A ist?
-
skullyan schrieb:
Also ich habe eine Klasse A, die ich in Header und Source aufgeteilt habe. Ich möchte nun von ihrem Header eine Klasse B ableiten. Nun sind aber die Methoden der Wurzelklasse A in der Source-Datei von A implementiert.
Wie löse ich dieses Problem? Muss ich sie einfach in den Source von B kopieren oder geht das irgendwie eleganter?
Verstehe ich nicht. Vielleicht kannst du ja kurz ein funktionsfähiges Codebeispiel zeigen.
-
// A.h /* HEADERGUARDS */ class A { public: A(int wert): m_ichBinA(wert) { } void huiWert(); protected: int m_ichBinA; }; /* HEADERGUARDS */// A.cpp #include "A.h" #include <iostream> void A::huiWert() { std::cout << m_ichBinA << std::endl; }// B.h /* HEADERGUARDS */ class B: public A { // blah blah, geht doch, oder was genau ist dein Problem? }; /* HEADERGUARDS */
-
Heck, hab natürlich ein:
#include "A.h"im
B.hvergessen
-
LP @ Ferropolis schrieb:
Heck, hab natürlich ein:
#include "A.h"im
B.hvergessenDu musst auch den Konstruktor noch aufrufen:
// [...] class B: public A { public: B(int wert) : A(wert) { } }; // [...]
-
LP @ Ferropolis schrieb:
// A.h /* HEADERGUARDS */ class A { public: A(int wert): m_ichBinA(wert) { } void huiWert(); protected: int m_ichBinA; }; /* HEADERGUARDS */// A.cpp #include "A.h" #include <iostream> void A::huiWert() { std::cout << m_ichBinA << std::endl; }// B.h /* HEADERGUARDS */ class B: public A { // blah blah, geht doch, oder was genau ist dein Problem? }; /* HEADERGUARDS */Ja geht, aber ein Objekt vom Typ B kann
A::huiWert();nicht aufrufen, weil ja nur der Header von A inkludiert ist. Dadurch ist huiWert(); nur deklariert, oder sehe ich das falsch?
-
Klar kann er das. Du sagst dem Compiler mit der Vorwärtsdeklaration lediglich, dass diese Funktion irgendwo definiert ist. Und der Linker macht dann die Funktion auch für andere Übersetzungseinheiten bekannt.
Wenn du jetzt mal die Definition weglässt, wirst du feststellen, dass der Compiler immernoch zufrieden ist. Aber der Linker findet dann die Definition der Funktion nicht. (sofern du irgendwo versuchst sie aufzurufen).
-
Das ist der Header der Wurzelklasse SERVER:
#ifndef _SERVER_ #define _SERVER_ #include <iostream> #include <windows.h> #include <winsock.h> using namespace std; class SERVER { private: WSADATA wsa; struct sockaddr_in srv, cli; SOCKET s, c; int cli_size; char port[80]; fd_set rfds; struct timeval tv; int retval; public: SERVER() {}; ~SERVER() { closesocket(s); } bool sockInit(); bool buildSock(); void structWrite(); bool zuhoeren(); bool acceptk(); }; #endifDas ist die Quelldatei von derselben:
#include "SERVER.h" bool SERVER::sockInit() { /* initialize windows sockets */ if (WSAStartup(MAKEWORD(1, 1), &wsa)) { cout << "WSAStartup() failed: " << (unsigned long)GetLastError() << endl; return EXIT_FAILURE; } cli_size = sizeof(sockaddr_in); return true; } bool SERVER::buildSock() { s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { cerr << "socket() failed" << endl; } return true; } bool SERVER::zuhoeren() { if (listen(s, 3) == -1) { cerr << "listen() failed" << endl; return EXIT_FAILURE; } return true; } void SERVER::structWrite() { cout << "Bitte Port eingeben: " << endl; cin >> port; srv.sin_addr.s_addr = INADDR_ANY; srv.sin_port = htons( (unsigned short int) atol(port)); srv.sin_family = AF_INET; if (bind(s, (struct sockaddr*)&srv, sizeof(srv)) == -1) { cerr << "bind() failed" << endl; return ; } } bool SERVER::acceptk() { for(int i = 0;;) { Sleep(200); c = accept(s, (struct sockaddr*)&cli, (int*)cli_size); i++; if(i< 5) break; } /*if (c == -1) { cerr << "accept() failed" << endl; return false; }*/ cout << "client from " << inet_ntoa(cli.sin_addr) << endl; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /* Don’t rely on the value of tv now! */ if (retval) cout << "Data is available now.\n" << endl; /* FD_ISSET(0, &rfds) will be true. */ else cout << "No data within five seconds.\n" << endl; return true; } // Deklaration von Funktionstemplate /* template<class T> inline T pow(T&); */ int main(int argc, char **argv) { SERVER ser; ser.sockInit(); if (argc != 1) { cerr << "usage: port\n" << "SERVER" << endl; return 1; } ser.buildSock(); ser.structWrite(); ser.zuhoeren(); ser.acceptk(); /* cout << "Bitte geben Sie eine Zahl ein. Diese wird dann potenziert ausgegeben: "; cin >> a; cout << "Die Potenz der eingegebenen Zahl betraegt: " << pow(a) << endl; char* Datei = new char[66]; //allokierung eines arrays mit 66 zeichen delete[] Datei; */ cin.sync(); cin.get(); return 0; } /* template<class T> inline T pow(T& a) { return a*a; } */Und das ist meine abgeleitete Klasse Client:#include "klie.h" void CLIENT::ausgeben()const { cout << "hallo" << endl; } bool SERVER::sockInit() { /* initialize windows sockets */ if (WSAStartup(MAKEWORD(1, 1), &wsa)) { cout << "WSAStartup() failed: " << (unsigned long)GetLastError() << endl; return EXIT_FAILURE; } cli_size = sizeof(sockaddr_in); return true; } bool SERVER::buildSock() { s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { cerr << "socket() failed" << endl; } return true; } bool SERVER::zuhoeren() { if (listen(s, 3) == -1) { cerr << "listen() failed" << endl; return EXIT_FAILURE; } return true; } void SERVER::structWrite() { cout << "Bitte Port eingeben: " << endl; cin >> port; srv.sin_addr.s_addr = INADDR_ANY; srv.sin_port = htons( (unsigned short int) atol(port)); srv.sin_family = AF_INET; if (bind(s, (struct sockaddr*)&srv, sizeof(srv)) == -1) { cerr << "bind() failed" << endl; return ; } } bool SERVER::acceptk() { for(int i = 0;;) { Sleep(200); c = accept(s, (struct sockaddr*)&cli, (int*)cli_size); i++; if(i< 5) break; } return true; } int main() { CLIENT kli; kli.acceptk(); kli.ausgeben(); cin.get(); return 0; }In diesem Fall funktioniert die Vererbung. Aber ich musste die implementierung der Methoden erst vom Source des Servers in den Source vom Client hineinkopieren.
Meine Frage war daher, ob es so üblich ist, denn wenn ich auch noch die SERVER.cpp-Sourcedatei in den Header von Client einfüge, bekomme ich natürlich die Fehlermeldung, dassmain()nicht überladen werden darf xD