self in Klassen [aus: swift]

Die Variable self wird nur gebraucht, wenn das Argument einer Funktion denselben Namen hat wie eine Klassenvariable.

Mit self.variable wird die Klassenvariable bezeichnet bzw. unterschieden von dem Argument.

class TipCalculator {
   let total: Double
   let taxPct: Double
   let subtotal: Double

   init(total: Double; taxPct: Double) {
       self.total = total      // Argumente erhalten
       self.taxPct = taxPct
       subtotal = total /(taxPct+1)   // keine Argumente
                                 // nur Klassenvariable
   }


}

aus: Swift 2 Tutorial

Abstrakte Klasse

Abstrakte Klassen enthalten keinen Code. Sie definieren nur die Schnittstelle. Sie können nicht instaziert werden!
Für die Instanzierung muss zuerst eine abgeleitete Klasse gebildet werden, welche die Schnittstellen definiert.
Abstrakte Funktionen sind ein Spezialfall bzw. der extremste Fall einer virtuellen Funktion. Sie werden pure virutal classes genannt.

// nicht instanzierbar
class B {

   public:                // können nur public sein
   virtual void f() = 0;  // = 0, damit pure ist
   virtual void g() = 0;
}

.

// abgeleitet Funktion ist instanzierbar
class B1 : public B {
  public:
      void f() override;   // kein virtual, dafür override
      void g() override;
}

B1 instanz_b;

Abstrakte Klassen sind für die Einheitlichkeit unter Code-Blöcken wichtig. Die Kompatibilität unter Klassen wird erzwungen. (Gleiche Abhandlungen heissen in allen Varianten gleich. )

Swift: Vererbung

  • Alle Swift Objekte sind Subklassen der Klasse NSObjekt oder einer ihrer Subklassen. Die Superklasse wird mit : in der Definition angegeben
    class A: Superklasse.
  • Das Init muss alle Paramter der Superklasse enthalten und weist dieser mit super.init(variable1 = variable1) einen Wert zu
  • Variablen der Superklasse können (ohne super) im init überschrieben werden.  variable2 = 5;
  • Funktionen werden ausserhalb des init() überschrieben und brauchend das keyword override.Bsp der iOS Developper Site
    class NamedShape {
        var numberOfSides = 0
        var name: String
        
        init(name: String) {
            self.name = name     // self für eigene Klassenvariable
        }
        
        func simpleDescription() -> String {
            return "A shape with \(numberOfSides) sides."
        }
    }


    class Square: NamedShape {
        var sideLength: Double
        
        init(sideLength: Double, name: String) {
            self.sideLength = sideLength   // eigene Klassenvariable
            super.init(name: name)    // Variable der Superklasse
            numberOfSides = 4 // Überschreibt Variable der Superklasse
        }
        
        func area() ->  Double {
            return sideLength * sideLength
        }
        
        override func simpleDescription() -> String {
            return "A square with sides of length \(sideLength)."
        }
    }
    let testSquare = Square(sideLength: 5.2, name: "my test square")
    testSquare.area()
    testSquare.simpleDescription()

..

Pointer C++: Wert auslesen

struct ImageInt16 {
.        short data[100]
};


Objekt bilden
2 Bilder werden abgelegt. Inhaltstruktur ist identisch. Der Typ der Speichervariable nicht.

ImageInt16     bild_1;          // enthält Wert
ImageInt16*    bild_2;          // enthält Speicherort, an dem Wert liegt


Variable auslesen

int result_1, result_2;

result_1 = bild_1.data[0];    
result_2 = bild_2->data[1];       // Objektreferenz
  //oder
result_2 = (*bild_2).data[1];    // Dereferenziert
.                                // Wert des Objekts

Der ersten zwei Wert aus dem Array wurden übergeben.
..

 

 

 

 

 

Objekt bearbeiten

Klasse

class MidiData {
.     public: 
.            // varibale
.            int pin;
.            double version;
.            int wait;        // in ms
.
.            // functions
.            MidiData(int pin, double version, int wait);   
.            string readStream( steam io);
.            string extractdata( string s);
}

Objekt definieren

MidiData system_2{ 8, 14.04, 5 }

system_2 ist ein Objekt der Klasse MidireadData. Im Objekt ist definiert, wo und mit welcher Version Midi gelesen wird.

Objeket bearbeiten

system_2.pin = 10;    // change data pin
system_2.wait = 10;   // change wait time

Zur Verarbeitung der Klasse wurden extra Memberfunktionen definiert.

string in_pin8 = system_2.readStream( input_8);
string data_pin8 = system_2.extractdata( in_pin8);

Über die Objektvariable system_2 können die Memberfunktionen aufgerufen werden.

 

Defintion Member functions

class MidiData {
.     public: 
.            // varibale
.            int pin;
.            double version;
.            int wait;        // in ms
.
.            // functions
.            MidiData(int pin, double version, int wait);   
.            string readStream( steam io);
.            string extractdata( string s);
}

Im public-Teil einer Funktion, wird die member-Funktion nur deklariert. Die Definition folgt ausserhalb.
Das gilt auch, wenn pro Klasse eine Datei erstellt wird.

Definition Member Function

<class>::<member-function>( <type> <argument> ) {
.      // Code
}
void Date::add_day( int n){
.      // Code
}
void Date:: month(){
.     // Code
}

..

Constructor C++

Eine Member-Funktion mit demselben Name wie die Klasse selbst, ist ein Constructor.

1. Konstruktor ohne Funktionen———————————————–

class MidiData {
. public: 
.     int pin;
.     double version;
.     int wait;        // in ms
.     MidiData(int pin, double version, int wait);  //Construct
.
}

Ein Objekt der Klasse kann nicht ohne Wertzuweisung definiert werden, eine Initialisierung ist zwingend notwendig beim Bilden eines Objektes. Die Initialiserung kann über eine List ober über den Constructor erfolgen:

MidireadData system_1 = { 13,  14.04, 10}  // list

MidireadData system_2 { 8, 14.04, 5 }  // constructor usually
MidireadData system_2( 8, 14.04, 5 )   // constructor old style

MidireadData system_3 = MidireadData{ 10, 14.04, 10 } //special

In der Initialisierung müssen alle Member-Variablen definiert werden.
Vgl. Bjarne Kapitel 9.4.2

2. Konstruktor für Klasse mit Funktionen ——————————-

class Date{
.      public:
.         // constructor
.         Date( int year, int month, int day);  
.         // member-functions
.         void add_day( int n);
.         int month();       // check error of number        
.
.      private:
.         int year, month, day;

};

Konstruktor mit Funktion:

Date::Date(int y_1,int m_1,int d_1)      
     : month( month1) {}

C++: Vektor per (const) reference

Es gibt zwei Prinzipien, wie man Vektoren (grosse Wertetabellen) übergeben kann:
1. Man will die Werte „nur“ verarbeiten. Die Tabelle bleibt gleich.
2. Man will Werte in der Tabelle ändern.

Werte nicht ändern
Wird ein Vektor per const Referenz übergeben const vector <type>& <name> , so verändert man aufgrund des Schlüsselwortes const die Einträge nicht (Bjarne 8.5.4). Anstatt per Referenz kann man die Werte auch traditionell per Pointer (per Adresse) übergeben, ebenfalls mit const.

Werte verändern (Bjarne 8.5.5)
Ist das Ziel, die Einträge zu ändern, so tut man dies z. B. so:

void init(vector <int> v){
.  //
}

————————————————————————————————————————-

Adresse erhalten

int i = 5;

// Variable für Adresse
int* adresse;

adresse = &i;      // die Adresse von i wird übergeben

Aus einer Adress-Variable einen Wert auselesen

int value_1;
value_1 = * adresse;

 

..