Ich veröffentliche hier mal mein derzeitiges experimentiermodell:
Code:
/*
* File: SensorHandler.hpp
* Author: pointhi
*
* Created on 26. April 2013, 14:13
*/
#ifndef SENSORHANDLER_HPP
#define SENSORHANDLER_HPP
#include <string>
#include <set>
#include <iostream>
// Achtung, Machbarkeitsanalyse, aus einfachheit mit public-variablen gemacht.
namespace SensorHandler {
class Baseclass { // Basisklasse um gennerelle Variablen und virtuelle Funktionen zu deklarieren
public:
std::string Name; // Variable, die jedes Objekt besitzt
Baseclass() {this->Name = "1234";}
void Output() {std::cout << "Hello Name: " << this->Name << std::endl;}
virtual Baseclass* GetItem(std::string Name) = 0;
virtual Baseclass* GetItem(signed int Id) = 0;
virtual signed int GetItemCount( void ) = 0;
// virtual void NewItem(std::string Name, std::string Type) = 0;
};
namespace Hardware {
class I2C : public SensorHandler::Baseclass {
public:
class Slave : public SensorHandler::Baseclass {
public:
Slave() {this->Name = "testclass";}
Baseclass* GetItem(std::string Name) {return NULL;}
I2c::Slave* GetItem(signed int Id) {return NULL;}
signed int GetItemCount( void ) {return 0;}
// void NewItem(std::string Name, std::string Type=NULL);
};
private:
// std::set<I2c::Slave> SlaveList;
I2c::Slave test; // Kindklasse
public:
I2c() {this->Name = "testtest";}
I2c::Slave* GetItem(std::string Name) {return &this->test;}
I2c::Slave* GetItem(signed int Id) {return &this->test;}
signed int GetItemCount( void ) {return 1;}
// void NewItem(std::string Name, std::string Type=NULL);
};
}
}
#endif /* SENSORHANDLER_HPP */
Es ist wirklich quick and dirty, aber es funktioniert derzeit wie gewollt. Aus einfachheit habe ich alles public gemacht, was im späteren Projekt natürlich nicht mehr sein darf. Auch fehlen noch ein paar essentielle klassen. Mir ist es derzeit nur darum gegangen die kommunikation in die subklassen zu testen, und eine sichere Objektverwaltung zu gewährleisten.
Als info, damit ihr euch auskennt wie ich mir das derzeit vorstelle:
Code:
virtual Baseclass* GetItem(std::string Name) = 0;
virtual Baseclass* GetItem(signed int Id) = 0;
Gibt einen Pointer auf die nächstfolgede Klasse. So können auch Standardvariablen wie der Name von jeder untergeordneten Klasse aufgerufen werden. In der klasse selber wird nicht die Klasse Baseclass sondern ein darauf aufbauender Typ angegeben. Mit diesem Typ werden auch die Kindelemente in der Klasse gespeichert. So kann diese Klasse auf alle Funktionen der Kindklasse zugreifen, eine allgemeine Funktion die nur durchnavigieren kann und nur auf Standardparameter und funktionen die jede klasse besitzt zugreifen kann. Durch die Spezialisierung wird auch vermieden dass falsche Kindklassen eingebunden werden können. (Z.b. das das I2C-System eine kindklasse von einem I2C-Slave wird.)
Es wird 2. Zugriffsmethoden geben, eine auf Namen bassierte und eine mit einer Id.
Code:
virtual signed int GetItemCount( void ) = 0;
Gibt die Anzahl der Kindklasse zurück, um sauber durchnavigieren zu können
Code:
virtual void NewItem(std::string Name, std::string Type) = 0;
Erstellt eine neue Kindklasse. Ich dachte vorher dass ich den Typ der Klasse übergebe, hab aber noch keine saubere Funktion dafür gefunden. Ich hab mir derzeit überlegt dass man einen Namen übergibt der den Klassentyp der Kindklasse repräsentiert, wenn es nur 1. Kindklassentyp gibt wird der Wert ignoriert und standardmäßig eine 0 übergeben.
Ich hoffe ihr kennt euch aus. Besonders das mit NewItem würde ich gerne noch überarbeiten. Was haltet ihr von der allgemeinen Idee, hier geht es derzeit nur darum in der Klasse zu navigieren. Das Dynamische Anlegen von Kindelementen ist z.b. noch nicht ausprobiert, wobei da villeicht eine Templateklasse für die Elementeverarbeitung ins spiel kommt, die von allen anderen Klassen die diese funktion benötigen geerbt wird.
Hier noch ein kleines Testprogramm von mir bezüglich der Navigation:
Code:
/*
* File: main.cpp
* Author: pointhi
*
* Created on 26. April 2013, 14:20
*/
#include <cstdlib>
#include <tr1/memory>
#include "SensorHandler.hpp"
using namespace std;
int main(int argc, char** argv) {
std::tr1::shared_ptr<SensorHandler::Baseclass> testClass(new SensorHandler::Hardware::I2c);
testClass->Output();
testClass->GetItem("123")->Output();
return 0;
}
Es schaut einfach nur ob ich durchnavigieren kann. Die Ausgabe ist die folgende:
Code:
Hello Name: testtest
Hello Name: testclass
Es zeigt dass beim ersten ->Output die erstellte Klasse angesprochen wird, beim 2. Output aber die aufgerufene kindklasse davon. Ich bin auch noch nicht sicher ob ich villeicht nicht shared_ptr als rückgabetyp geben soll, um speicherlecks und fehlzugriffe zu vermeiden. Ich hab mit diesen Klassen aber noch sehr wenig erfahrung.
mfg, pointhi
Lesezeichen