DOMANDA C++ - impedire l'utilizzo di static member function per le istanze di una classe

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
In basso ho una classe chiamata Vector con al suo interno una static member function chiamata getDotProduct().
Come si vede da main, l'utilizzo voluto è "float dotProduct = Vector::getDotProduct(v1, v2);" insomma usando il nome della classe come una sorta di namespace, però allo stesso tempo vorrei impedire la chiamata di questa member function ad istanze di Vector, percui vorrei impedire una chiamata del tipo "float dotProduct = v3.getDotProduct(v1,v2);" perchè non ha senso chiamare v3 quando il risultato ritornato dalla funzione non ha nulla a che vedere con v3.
Percui, c'è un mondo per impedire quest'ultimo tipo di chiamata? :)

Codice:
#include <iostream>
using namespace std;

class Vector {
public:
    Vector(float _x = 0, float _y = 0, float _z = 0) : x{ _x }, y{ _y }, z{ _z } { computeMagnitude(); }
    friend ostream& operator<<(ostream&, const Vector&);
    friend Vector operator*(const Vector&, const Vector&);
    friend Vector operator+(const Vector&, const Vector&);
    friend Vector operator-(const Vector&, const Vector&);
    inline void computeMagnitude() { magnitude = sqrt(x*x + y*y + z*z); }
    inline Vector getNormalizedVector() { return Vector(x / magnitude, y / magnitude, z / magnitude); }
    static inline float getDotProduct(const Vector& lhs, const Vector& rhs) { Vector v = lhs*rhs; return v.x + v.y + v.z; }
    float x;
    float y;
    float z;
    float magnitude;
};
ostream& operator<<(ostream& stream, const Vector& v)
{
    return stream << "x,y,z{" << v.x << "," << v.y << "," << v.z << "} magnitude =" << v.magnitude;
}
Vector operator*(const Vector& lhs, const Vector& rhs)
{
    return Vector(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);
}
Vector operator+(const Vector& lhs, const Vector& rhs)
{
    return Vector(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
}
Vector operator-(const Vector& lhs, const Vector& rhs)
{
    return Vector(lhs.x + (-rhs.x), lhs.y + (-rhs.y), lhs.z + (-rhs.z));
}

int main()
{
    Vector v1(3, 3, 3), v2(2, 2, 2);
    Vector v3 = Vector(-1,3,4).getNormalizedVector();
    float dotProduct = Vector::getDotProduct(v1, v2);
    cout << dotProduct << endl;
    return 0;
}
 
Ultima modifica:

BAT

Moderatore
Staff Forum
Utente Èlite
22,942
11,577
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
Ho un dubbio: è corretta la definizione di classe?
di C++ non sono pratico però mi pare di ricordare che sui membri statici funziona più o meno come Java, dove una funzione dichiarata static NON dovrebbe poter accedere a membri non statici (in Java un codice simile non viene accettato dal compilatore)
invece la funzione statica del prodotto scalare che hai scritto vedo che accede direttamente alle coordinate v.x/v.y/v.z del vettore v (che crea in essa) ma non dovrebbe farlo (sempre che funzioni come in Java naturalmente); se ho detto cavolate faccio ammenda, ma il C++ proprio non me lo ricordo.

Vedo poi che hai ridefinito l'operatore moltiplicazione in modo da ottenere un nuovo vettore come moltiplicazione di coordinate di quelli passati come parametri...
dal punto di vista del codice puoi fare quel che vuoi però matematicamente parlando non mi ricordo che esista una simile operazione (c'è il prodotto scalare -o prodotto punto- ed il prodotto vettoriale non la semplice moltiplicazione di coordinate), per cui a che pro ridefinire l'operatore "*" ? Secondo me dovresti invece semplicemente definire dotProduct(...) (senza il "get" ed eseguire le moltiplicazioni e la somma finale dentro di essa)

Sulla chiamata in sé non so se si possa impedire ma in ogni caso chi usa la funzione sarebbe tenuto a chiamarla correttamente ben sapendo che non c'è alcun bisogno di costruire un terzo oggetto prima di chiamare una funzione statica. Insomma l'errore qui non lo fai tu ma chi usa la funzione: le funzioni statiche non sono legate ad oggetti particolari, quindi non ha senso crearne uno per l'invocazione.
 
Ultima modifica:

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Ho un dubbio: è corretta la definizione di classe?
di C++ non sono pratico però mi pare di ricordare che sui membri statici funziona più o meno come Java, dove una funzione dichiarata static NON dovrebbe poter accedere a membri non statici (in Java un codice simile non viene accettato dal compilatore)
invece la funzione statica del prodotto scalare che hai scritto vedo che accede direttamente alle coordinate v.x/v.y/v.z del vettore v (che crea in essa) ma non dovrebbe farlo (sempre che funzioni come in Java naturalmente); se ho detto cavolate faccio ammenda, ma il C++ proprio non me lo ricordo.

Il codice compila e funziona senza errori, non sapevo di quella regola ma suppongo si applichi alle private variable di una classe che possono essere comunque modificate dalle member function della classe, in questo caso però tutte le mie variabili sono public variables quindi nessun problema, ed anche se fossero private suppongo si potrebbe aggirare aggiungendo getters e setters per le variabili della classe Vector e chiamare quelli nella static function.


Vedo poi che hai ridefinito l'operatore moltiplicazione in modo da ottenere un nuovo vettore come moltiplicazione di coordinate di quelli passati come parametri...
dal punto di vista del codice puoi fare quel che vuoi però matematicamente parlando non mi ricordo che esista una simile operazione (c'è il prodotto scalare -o prodotto punto- ed il prodotto vettoriale non la semplice moltiplicazione di coordinate), per cui a che pro ridefinire l'operatore "*" ? Secondo me dovresti invece semplicemente definire dotProduct(...) (senza il "get" ed eseguire le moltiplicazioni e la somma finale dentro di essa)

Su questo concordo, la moltiplicazione è abbastanza inutile ed usata soltanto dentro getDotProduct() quindi posso scrivere il codice direttamente lì, un esperimento non riuscito xD

Sulla chiamata in sé non so se si possa impedire ma in ogni caso chi usa la funzione sarebbe tenuto a chiamarla correttamente ben sapendo che non c'è alcun bisogno di costruire un terzo oggetto prima di chiamare una funzione statica. Insomma l'errore qui non lo fai tu ma chi usa la funzione: le funzioni statiche non sono legate ad oggetti particolari, quindi non ha senso crearne uno per l'invocazione.

Chiaro, però mi infastidisce che se scrivo "v1." l'autocomplete me lo suggerisca come opzione, è un problema banale ma se possibile volevo rendere quella chiamata illegale (rendendolo quindi invisibile all'intellisense) senza dover togliere quella static function da dentro la classe e quindi mantenendo la possibilità di usare il nome classe come fosse un namespace, scrivendo "float dotProduct = Vector::dotProduct(v1, v2);"
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!