Come da titolo, ho un dubbio relativo a che tipo di accessibilità (public, private o protected) fornire a un metodo.
Il dubbio è relativo a un metodo reverseRecursiveUtility della seguente classe singlyLinkedList
(spiego un po' di preliminari, ma il dubbio vero e proprio sta sotto, alla voce "IL DUBBIO", mentre la domanda sta alla voce "LA DOMANDA" )
Codice: Seleziona tutto
#include<iostream>
struct node
{
int data;
node* next;
node(int val = 0)
: data(val), next(nullptr)
{ }
};
class singlyLinkedList
{
private:
node* head;
public:
singlyLinkedList();
~singlyLinkedList();
void push(int val);
void reverse();
node* reverseRecursiveUtility(node* myHead); //questo è il metodo su cui nutro dubbi
void reverseRecursive();
Venendo al problema, per questa lista ho sviluppato due algoritmi di "inversione".
Il primo è reverse, ed è quello semplice.
È l'algoritmo iterativo, non dà problemi, ma per chiarezza scrivo il codice:
Codice: Seleziona tutto
void singlyLinkedList::reverse()
{
//~ //Time Complexity: O(n)
//~ //Space Complexity: O(1)
if (head == nullptr || head->next == nullptr)
return;
//~ //Inizializzo i puntatori current, previous e next
node* current = head;
node* prev = nullptr;
node* next = nullptr;
while (current != nullptr)
{
//~ //Immagazzino next
next = current->next;
//~ //Inverto current->next
current->next = prev;
//~ //Muovo i puntatori avanti di una posizione.
prev = current;
current = next;
}
//~ //L'ultimo nodo diventa la testa
head = prev;
}
IL DUBBIO
La parte su cui ho il mio dubbio è il metodo reverseRecursiveUtility.
Questo metodo viene richiamato dal metodo vero e proprio che si occupa della inversione:
Codice: Seleziona tutto
void singlyLinkedList::reverseRecursive()
{
head = reverseRecursiveUtility(head);
}
Codice: Seleziona tutto
node* singlyLinkedList::reverseRecursiveUtility(node* myHead)
{
if (myHead == nullptr || myHead->next == nullptr)
return myHead;
/* inverto la lista restante
e metto il primo elemento alla fine */
node* rest = reverseRecursiveUtility(myHead->next);
myHead->next->next = myHead;
/* barbatrucco */
myHead->next = nullptr;
/* ritorno rest */
return rest;
}
Questa funzione reverseRecursiveUtility ritorna un puntatore node*.
Usata come viene fatto in reverseRecursive, ritorna al chiamante la "head" della lista.
Pertanto a me non piace molto che questo metodo sia pubblico. Perché "in un certo senso" espone dettagli interni della classe.
"In un certo senso" è virgolettato perché ovviamente, qualora reverseRecursiveUtility fosse chiamata dall'esterno della classe, non si potrebbe usare come parametro la vera e propria head della lista, che è privata.
E quindi il problema di esporre la variabile privata "head" non sussisterebbe.
Mi sto però chiedendo quale sia il modo più sensato di gestire in generale questo tipo di "utility" all'interno di una classe.
Per questo tipo di "utility", intendo funzioni che ritornino puntatori o reference a variabili private della classe, che però non si vuole che siano esposte (quindi non intendo "roba" del tipo operator[] )
Ha senso impostare il metodo reverseRecursiveUtility come "private"?
Spero di essere stato chiaro.
Grazie in anticipo.