Sto provando a creare una classe che ha un membro privato che è una matrice. Non conosco la dimensione della matrice e non lo sarà fino a quando il valore non viene passato al costruttore. Qual è il modo migliore per definire la funzione di costruzione della classe e la definizione nel file .h per consentire questa dimensione variabile dell'array?Matrice come membro privato della classe
risposta
Se si desidera un array "reale" in stile C, è necessario aggiungere un membro privato dell'indicatore alla classe e allocare dinamicamente la memoria per esso nel costruttore (con nuovo). Ovviamente non devi dimenticare di liberarlo nel distruttore.
class YourClass
{
private:
int * array;
size_t size;
// Private copy constructor operator to block copying of the object, see later
// C++03:
YourClass(const YourClass &); // no definition
// C++11:
YourClass(const YourClass&) = delete;
public:
YourClass(size_t Size) : array(new int[Size]), size(Size)
{
// do extra init stuff here
};
~YourClass()
{
delete [] array;
}
};
per fare questo lavoro più facile, si può considerare di utilizzare un puntatore intelligente (ad esempio, un boost::scoped_array in C++ 03, o semplice std::unique_ptr
in C++ 11), che si può inizializzare utilizzando l'inizializzazione elenco prima del costruttore o semplicemente nel costruttore.
class YourClass
{
private:
boost::scoped_array<int> array; // or in C++11 std::unique_ptr<int[]> array;
size_t size;
public:
YourClass(size_t Size) : array(new int[Size]), size(Size)
{
// do extra init stuff here
}
// No need for a destructor, the scoped_array does the magic
};
Entrambe queste soluzioni producono oggetti noncopyable (non è stato specificato se dovessero essere copiabile e la loro copia semantica); se la classe non deve essere copiata (cosa che accade più volte), entrambi sono ok e il compilatore genererà un errore se si tenta di copiare/assegnare una classe a un'altra, nel primo caso perché la copia predefinita il costruttore è stato sovraccaricato con uno privato (o cancellato in C++ 11), nel secondo caso perché boost::scoped_array
e std::unique_ptr
non sono copiabili.
Se, invece, si desidera disporre di oggetti copiabili, è necessario decidere se si desidera creare una copia che condivide l'array (quindi, solo una copia puntatore) o se si desidera creare un nuovo array separato per l'altro oggetto.
Nel primo caso, è necessario prestare molta attenzione prima di liberare la memoria allocata, poiché altri oggetti potrebbero utilizzarla; un contatore di riferimento è la soluzione più comune. Puoi essere aiutato in questo da boost::shared_array (o std::shared_ptr
in C++ 11), che fa tutto il monitoraggio funziona automaticamente per te.
Se invece si desidera eseguire una "copia profonda", sarà necessario allocare la nuova memoria e copiare tutti gli oggetti dell'array sorgente nell'array di destinazione. Questo non è completamente banale da fare correttamente, e di solito è realizzato attraverso il "copy and swap idiom".
Eppure, la soluzione più semplice è quella di utilizzare un std::vector
come membro privato: sarebbe gestire tutte le cose allocazione/deallocazione di per sé, costruendo/autodistruggersi correttamente quando l'oggetto della vostra classe è costruito/distrutto. Inoltre, implementa la semantica della copia profonda fuori dalla scatola. Se è necessario consentire ai chiamanti di accedere al vettore di sola lettura, è possibile scrivere un getter che restituisce un riferimento const_iterator
o const
all'oggetto vector
.
L'utilizzo di un vettore std :: è la migliore. Se hai bisogno di passarlo a una funzione che si aspetta un puntatore a un array (come fa spesso il GSL), puoi ancora passare &vec[0]
...
- 1. const inizializzazione di matrice membro della classe
- 2. Come ereditare un membro privato in JavaScript?
- 3. Come scrivere accessor per array 2D (membro privato)
- 4. C++ Lambda cattura membro della classe privata
- 5. Puntatore a un membro di dati privato di una classe
- 6. Riferimento come inizializzazione del membro della classe
- 7. sintassi membro privato classi ES6
- 8. Javascript membro privato su prototipo
- 9. estende della classe con il costruttore privato
- 10. Perché ricevo CA2000 con un membro privato IDisposable all'interno della mia classe IDisposable?
- 11. boost mutex strano errore con membro privato
- 12. Perché questa funzione amico non può accedere a un membro privato della classe?
- 13. Perché l'accesso alla riflessione può essere protetto/membro privato della classe in C#?
- 14. Usando la funzione amico, possiamo sovrascrivere il membro privato della classe?
- 15. Il costruttore ha chiamato immediatamente una matrice di oggetti come membro della classe?
- 16. Perché la classe interna può accedere a un membro privato di un'altra classe interiore?
- 17. Variabile membro membro della classe derivata accesso in funzione virtuale
- 18. Puntatore funzione al membro della classe statico?
- 19. Come inserire EasyMock mock nel campo privato della classe testata
- 20. Il costruttore della classe interna privata è anche privato?
- 21. Funzione membro variabile della classe template
- 22. statica costante dichiarazione di membro della classe
- 23. Classe membro statica: dichiarare la classe private e il membro della classe package-private?
- 24. dattiloscritto accesso membro della classe base
- 25. C++: valori predefiniti nel membro della classe
- 26. Perché è possibile accedere al membro privato di una classe nidificata mediante i metodi della classe di inclusione?
- 27. membro statico della classe di tipo propria classe
- 28. Passaggio membro della classe di classe base costruttore (per riferimento)
- 29. Impossibile accedere membro protetto della classe base dalla classe derivata
- 30. Accesso classe annidata privato
Per gli array, dovrai assicurarti di usare ' scoped_array', non 'scoped_ptr'. –
corretto, grazie. Ottengo sempre la cancellazione [], ma a volte mi sono dimenticato delle versioni dell'array dei puntatori intelligenti. –
L'unico snigging è se YourClass sta per essere copiato, perché scoped_ * non è copiato in boost. Ciò non è specificato nella domanda comunque, quindi +1 comunque. – Skurmedel