Il metodo manipola le variabili globali, contrassegna const?

1

Ho scritto una classe ShaderWrapper in C ++, che avvolge gli shader OpenGL. Nel costruttore ho generato l'oggetto shader OpenGL, ma questo metodo mi restituisce solo un handle / id di tipo int. L'oggetto actuall shader è memorizzato da qualche parte nello spazio globale. Quindi gli oggetti ShaderWrapper devono solo memorizzare un numero intero ciascuno.

In questa classe ho metodi, che assomigliano a questo:

void ShaderWrapper::setFloat(char* name, float value)
{
    glUniform1f(glGetUniformLocation(shaderID, name), value);
}

Questo metodo in realtà non modifica alcun dato nell'oggetto ShaderWrapper , ma modifica alcuni dati nell'oggetto shader OpenGL.

Il mio IDE (Visual Studio + Resharper) suggerisce che questo metodo dovrebbe essere contrassegnato come const . E 'un buono stile? Marcare come const sembra strano, dato che in realtà cambio alcuni dati, non solo nell'oggetto wrapper stesso, ma nell'oggetto OpenGL nascosto.

    
posta Jakube 31.07.2017 - 11:05
fonte

2 risposte

4

Mantieni non const.

Suppongo che per gli utenti di ShaderWrapper l'oggetto OpenGL sottostante sia un dettaglio di implementazione di cui non hanno bisogno e che vogliono essere interessati. Quindi dal punto di vista dell'utente setFloat() fa cambia lo stato osservabile di un oggetto ShaderWrapper . Ecco perché non dovrebbe essere const anche se tecnicamente potrebbe essere.

Dove dovresti prendere in considerazione la costanza è il parametro name . Qualche ragione particolare per cui non può essere un const char* ? Non sembra che il char array venga modificato ovunque, quindi const sembra appropriato. Ti permetterebbe anche di passare una stringa letterale a setFloat() , che al momento è impossibile.

Spunti di riflessione

(con l'avvertenza che non conosco affatto OpenGL)

Mi sembra che quello che ti interessa davvero è una combinazione di uno shader e di qualche proprietà con nome, perché è l'entità su cui lavori effettivamente.

Potresti introdurre una Location di conseguenza e cambiare ShaderWrapper in modo che lo scopo sia di essere un gestore risorse per un oggetto shader OpenGL e una fabbrica per oggetti Location . Per il vero lavoro, allora hai funzioni indipendenti che prendono come parametro un Location& o const Location& .

È un po 'come l'approccio container più iteratore in quel Location oggetti "index" in uno shader e vengono invalidati una volta che il loro ShaderWrapper muore. Ovviamente questo crea il problema degli oggetti Location che pendono possibilmente. Quindi forse un ShaderID deve diventare una cosa simile a shared_ptr che gestisce la proprietà condivisa e uccide l'oggetto OpenGL quando muore l'ultimo Location .

Ovviamente tutto ciò è solo un ruvido giro di brainstorming. Il punto è: vedo qui la tentazione di creare una "classe di Dio" e l'opportunità di resistere a quella tentazione e creare un design possibilmente più elegante, più sicuro e più facile da usare che combini diversi piccoli pezzi con scopi ben specifici. O alla fine avrai capito esattamente perché vuoi quella grande e potente singola classe in questa situazione.

    
risposta data 31.07.2017 - 12:15
fonte
3

Logicamente stai mutando lo shader, non importa che tu abbia esternalizzato lo storage effettivo a una tabella di ricerca globale. Quindi questo metodo non dovrebbe essere richiamabile su una visualizzazione costante dello shader e il metodo non dovrebbe essere const .

Potresti anche voler aggiungere un wrapper per location , in modo da poter modellare un riferimento di posizione mutabile e costante e quindi supportare solo ottenere una posizione mutabile su un oggetto shader mutabile. Ciò minimizza la quantità di codice interessato dalla mancata corrispondenza tra la semantica di C ++ e l'API OpenGL.

    
risposta data 31.07.2017 - 11:44
fonte

Leggi altre domande sui tag