UP | HOME

C++ - Definizione di classi

Table of Contents

Introduzione

La creazione di una classe in C++ coinvolge la definizione di una struttura che raggruppa dati (variabili) e funzionalità (metodi) correlati. Una classe fornisce un modello per creare oggetti, che sono istanze specifiche di quella classe.

Ecco i passi generali per creare una classe in C++:

Definire il file di intestazione (header file): Inizia creando un file di intestazione (con estensione .h o .hpp) per la tua classe. Questo file conterrà la dichiarazione della classe, inclusi i membri di dati (variabili membro) e i prototipi dei metodi.

Dichiarare la classe: All'interno del file di intestazione, utilizza la parola chiave class seguita dal nome della classe per dichiarare la classe. Ad esempio, class MyClass.

Definire i membri di dati: All'interno della classe, dichiara le variabili membro che rappresentano i dati associati alla classe. Questi membri di dati possono essere pubblici (accessibili direttamente) o privati (accessibili solo tramite metodi della classe).

Definire i metodi: Dopo la dichiarazione dei membri di dati, dichiara i prototipi dei metodi all'interno della classe. I metodi rappresentano le funzionalità e le operazioni associate alla classe. Possono essere metodi pubblici (accessibili esternamente alla classe) o metodi privati (accessibili solo internamente alla classe).

Implementare la classe (file di implementazione): Oltre al file di intestazione, puoi creare un file di implementazione (con estensione .cpp) per definire l'implementazione dei metodi della classe. In questo file, includi il file di intestazione e implementa i metodi dichiarati nella classe.

Utilizzare la classe: Una volta definita la classe e implementati i suoi metodi, puoi utilizzare la classe nel tuo programma principale o in altre parti del codice, creando oggetti di quella classe e richiamando i suoi metodi.

Esempio

In questo esempio, il file "MyClass.h" contiene la dichiarazione della classe MyClass che include un oggetto myLoRaObject di tipo LoRaE220. Il file "MyClass.cpp" implementa i metodi della classe MyClass utilizzando l'oggetto myLoRaObject per inviare e ricevere dati.

Il file "main.cpp" include il file di intestazione "MyClass.h" e crea un oggetto myObject di tipo MyClass. Nel metodo setup(), viene chiamato il metodo setup() dell'oggetto myObject per inizializzare l'oggetto myLoRaObject. Nel loop principale (loop()), vengono chiamati i metodi sendData() e receiveData() dell'oggetto myObject per inviare e ricevere dati tramite l'oggetto myLoRaObject.

Assicurati di includere correttamente la libreria LoRaE220.h nel tuo progetto e di configurare correttamente la comunicazione seriale (Serial2) in base alla tua configurazione specifica.

Definizione del file MyClass.h

#ifndef MYCLASS_H
#define MYCLASS_H

#include <LoRa_E220.h>

class MyClass {
  LoRa_E220 myLoRaObject;

public:
  MyClass();
  void setup();
  void sendData(const char* data);
  void receiveData();
};

#endif

Definizione del file MyClass.cpp

#include "MyClass.h"

MyClass::MyClass() : myLoRaObject(&Serial2) {
  // Costruttore della classe
}

void MyClass::setup() {
  myLoRaObject.begin();
  myLoRaObject.setFrequency(868.0);
  myLoRaObject.setPower(20);
}

void MyClass::sendData(const char* data) {
  myLoRaObject.send(data);
}

void MyClass::receiveData() {
  char receivedData[64];
  myLoRaObject.receive(receivedData);
  // Fai qualcosa con i dati ricevuti
}

La notazione MyClass::MyClass() : myLoRaObject(&Serial2) {} indica l'implementazione del costruttore della classe MyClass. Vediamo cosa significa nel dettaglio:

MyClass::MyClass(): Questa parte indica che stiamo definendo il costruttore della classe MyClass. Il doppio :: viene utilizzato per indicare che il costruttore appartiene alla classe MyClass.

": myLoRaObject(&Serial2)" Questa parte è chiamata "elenco di inizializzazione" e viene utilizzata per inizializzare le variabili membro della classe. Nel nostro caso, stiamo inizializzando la variabile membro myLoRaObject di tipo LoRaE220 con l'argomento &Serial2.

{}: Le parentesi graffe rappresentano il corpo del costruttore, che può contenere ulteriori istruzioni o logica personalizzata da eseguire durante la creazione di un oggetto MyClass.

Definizione di main.cpp

#include <Arduino.h>
#include "MyClass.h"

MyClass myObject;

void setup() {
  myObject.setup();
}

void loop() {
  myObject.sendData("Hello, LoRa!");  // Esempio di invio dati
  myObject.receiveData();  // Esempio di ricezione dati

  // Esegui il tuo codice
}

Puntatore this

Il puntatore this è un puntatore implicito disponibile all'interno dei metodi di una classe in C++. Esso rappresenta l'indirizzo di memoria dell'oggetto corrente su cui il metodo viene chiamato. Può essere utilizzato per accedere ai membri di dati e ai metodi dell'oggetto all'interno dei suoi stessi metodi. n questo esempio, abbiamo una classe MyClass con un membro di dati privato value. Nel metodo printValue(), utilizziamo il puntatore this per accedere al membro di dati value dell'oggetto corrente. Stampiamo il valore di value e l'indirizzo di memoria dell'oggetto utilizzando this.

All'interno del metodo printValue(), this rappresenta l'indirizzo di memoria dell'oggetto su cui il metodo è chiamato. Possiamo utilizzare this per accedere a tutti i membri di dati e i metodi dell'oggetto, come nel caso di this->value per accedere al membro di dati value.

#include <iostream>

class MyClass {
private:
  int value;

public:
  MyClass(int value) : value(value) {}

  void printValue() {
    std::cout << "Value: " << this->value << std::endl;
    std::cout << "Address: " << this << std::endl;
  }
};

int main() {
  MyClass obj(42);
  obj.printValue();

  return 0;
}

ed ecco l'output

Value: 42
Address: 0x7ffc12a561c0

Overload di metodi

In questo esempio, il file "LoRaE220.h" contiene la definizione della classe LoRaE220. All'interno della classe, sono definiti tre metodi send() sovraccaricati che accettano rispettivamente un parametro di tipo const char*, int e float. Ogni metodo ha una logica specifica per gestire il tipo di dato passato.

Nel file "main.cpp", viene istanziato un oggetto lora di tipo LoRaE220. Vengono dichiarate una stringa di tipo const char* chiamata message, un numero intero chiamato number e un valore float chiamato value. I metodi sovraccaricati send() dell'oggetto lora vengono chiamati con i parametri corrispondenti.

File "LoRaE220.h"

#ifndef LORA_E220_H
#define LORA_E220_H

class LoRa_E220 {
public:
  void send(const char* data) {
    // Logica per inviare dati di tipo const char*
    // ...
  }

  void send(int number) {
    // Logica per inviare un numero intero
    // ...
  }

  void send(float value) {
    // Logica per inviare un valore float
    // ...
  }

  // Altri metodi e membri della classe...
};

#endif

File "main.cpp"

#include <iostream>
#include "LoRa_E220.h"

int main() {
  LoRa_E220 lora;

  const char* message = "Hello, LoRa!";
  int number = 123;
  float value = 3.14;

  lora.send(message);  // Invia dati di tipo const char*
  lora.send(number);   // Invia un numero intero
  lora.send(value);    // Invia un valore float

  return 0;
}

Overloading di metodi definiti in altre classi

er fare l'overloading dei metodi definiti in un'altra classe, puoi estendere la classe esistente e aggiungere nuovi metodi con la stessa firma ma con comportamenti diversi. Ecco un esempio di come fare ciò:

Supponiamo che tu abbia una classe chiamata OriginalClass con un metodo doSomething() che accetta un parametro intero:

File "OriginalClass.h":

#ifndef ORIGINALCLASS_H
#define ORIGINALCLASS_H

class OriginalClass {
public:
  void doSomething(int value);
};

#endif

File "OriginalClass.cpp":

#+beginsrc cpp #include "OriginalClass.h" #include <iostream>

void OriginalClass::doSomething(int value) { std::cout << "OriginalClass::doSomething(int): " << value << std::endl; } Ora vuoi fare l'overloading del metodo doSomething() aggiungendo un nuovo comportamento quando viene passato un parametro di tipo float. Puoi creare una nuova classe chiamata ExtendedClass che estende OriginalClass e definisce il metodo sovraccaricato: #+endsrc cpp

File "ExtendedClass.h":

#ifndef EXTENDEDCLASS_H
#define EXTENDEDCLASS_H

#include "OriginalClass.h"

class ExtendedClass : public OriginalClass {
public:
  using OriginalClass::doSomething;  // Importa il metodo originale dalla classe base
  void doSomething(float value);     // Sovraccarica il metodo con un parametro float
};

#endif

File "ExtendedClass.cpp":

#include "ExtendedClass.h"
#include <iostream>

void ExtendedClass::doSomething(float value) {
  std::cout << "ExtendedClass::doSomething(float): " << value << std::endl;
}

Nel file di intestazione "ExtendedClass.h", abbiamo incluso il file di intestazione "OriginalClass.h" e definito una nuova classe ExtendedClass che eredita pubblicamente da OriginalClass. Abbiamo anche utilizzato using per importare il metodo originale doSomething() dalla classe base.

Nel file di implementazione "ExtendedClass.cpp", abbiamo implementato il nuovo metodo doSomething() che accetta un parametro di tipo float e fornisce un nuovo comportamento.

Ora puoi utilizzare la classe ExtendedClass nel tuo programma principale o in altre parti del codice, che ti consentirà di utilizzare i metodi sovraccaricati:

File "main.cpp":

#include "ExtendedClass.h"

int main() {
  ExtendedClass obj;

  int intValue = 123;
  float floatValue = 3.14;

  obj.doSomething(intValue);   // Chiamata al metodo doSomething() della classe base
  obj.doSomething(floatValue); // Chiamata al metodo sovraccaricato della classe derivata

  return 0;
}

In questo esempio, abbiamo creato un oggetto obj di tipo ExtendedClass e chiamato sia il metodo doSomething() ereditato dalla classe base OriginalClass che il metodo sovraccaricato doSomething() della classe ExtendedClass.

Output:

OriginalClass::doSomething(int): 123
ExtendedClass::doSomething(float): 3.14

In questo modo, puoi fare l'overloading dei metodi definiti in un'altra classe creando una nuova classe derivata e aggiungendo nuovi metodi con la stessa firma ma con comportamenti diversi.

Author: ARI people

Created: 2023-07-10 lun 16:06

Validate