View Full Version : [C++] Array di oggetti e costruttore non default
Ciao a tutti!
Ieri sera mi sono trovato ad affrontare questo problema:
data una classe di esempio, desidero creare un array dinamico di oggetti di classe Prova, e richiamare su questi un costruttore non con argomenti di default (con x e y variabili già definite nel corso del programma):
class Prova {
private:
int numeretto;
public:
Prova(int n = 5) {
numeretto = n;
}
};
[...]
Prova *prova_ptr = new Prova[x](y);
Ricevo però un errore di sintassi su quest'ultima riga.
Ho fatto una ricerca leggendo che effettivamente la sintassi che uso è corretta, mentre su un altro sito ho letto che in questi casi si consiglia di usare vector, ma in che modo dovrei passargli l'argomento del costruttore?
Grazie per le dritte =)
marra11mg
21-04-2008, 13:38
Prova *prova_ptr = new Prova[x](y);
Questa sintassi è sbagliata, o per lo meno il mio compilatore non la accetta.
io risolvo cosi
const int numero_classi = 7;
// puntatore a puntatori di oggetti
Prova** puntatore = new Prova*[numero_classi];
for (int i = 0; i < numero_classi; i++)
{
// richiamo il costruttore per ogni singolo elemento istanziato
// e gli assegno il valore dell'indice corrente i
puntatore[i] = new Prova(i);
}
Compilatore: MSVC++ 9.0
OS: WinXP Professional
Due sono le soluzioni "semplici".
Una e' quella vista sopra, con l'uso dei puntatori, che comporta pero' il doversi gestire la memoria cosi' allocata.
Un'altra e' quella di usare il vector, in modo simile al seguente
#include <iostream>
#include <vector>
using namespace std;
class Prova {
private:
int numeretto;
public:
Prova(int n = 5) {
numeretto = n;
}
};
// Prova *prova_ptr = new Prova[x](y);
int main()
{
vector<Prova> v(5,Prova(10));
}
Questa sintassi è sbagliata, o per lo meno il mio compilatore non la accetta.
io risolvo cosi
const int numero_classi = 7;
// puntatore a puntatori di oggetti
Prova** puntatore = new Prova*[numero_classi];
for (int i = 0; i < numero_classi; i++)
{
// richiamo il costruttore per ogni singolo elemento istanziato
// e gli assegno il valore dell'indice corrente i
puntatore[i] = new Prova(i);
}
Compilatore: MSVC++ 9.0
OS: WinXP Professional
Sì, questa potrebbe essere sicuramente una soluzione, ma ancora non fa esattamente al mio caso, perchè sto cercando di aggiungere una nuova funzionalità ad un programma che avevo già scritto, quindi così facendo sarei costretto a fare qualche modifica qua e là al codice di tutta la classe...
Davvero non c'è modo di richiamare un costruttore con argomenti non di default in questi casi?
Edit: non avevo letto il post di marco.r... dunque è assodato che new non permette di passare argomenti al costruttore quando si creano array?
Penso che userò vector allora :D
scusa ma dato che il costruttore della classe Prova ha il valore di default al parametro, che ci vuole a fare così?
class Prova
{
public:
Prova()
{
Prova(5);
}
Prova(int n)
{
...
}
};
:Prrr:
scusa ma dato che il costruttore della classe Prova ha il valore di default al parametro, che ci vuole a fare così?
class Prova
{
public:
Prova()
{
Prova(5);
}
Prova(int n)
{
...
}
};
:Prrr:
Scusa, ma credo che questo non funzioni :mbe:
Chiamare un costruttore, non dovrebbe creare un nuovo oggetto? :stordita:
scusa ma dato che il costruttore della classe Prova ha il valore di default al parametro, che ci vuole a fare così?
class Prova
{
public:
Prova()
{
Prova(5);
}
Prova(int n)
{
...
}
};
:Prrr:
Non credo che risolva il mio problema... così facendo, con
Prova *prova_ptr = new Prova[x];
vengono comunque creati x oggetti Prova invocando il costruttore di default, mentre io vorrei poter passare come argomento una seconda variabile :eek:
Ciao a tutti!
Ieri sera mi sono trovato ad affrontare questo problema:
data una classe di esempio, desidero creare un array dinamico di oggetti di classe Prova, e richiamare su questi un costruttore non con argomenti di default (con x e y variabili già definite nel corso del programma):
class Prova {
private:
int numeretto;
public:
Prova(int n = 5) {
numeretto = n;
}
};
[...]
Prova *prova_ptr = new Prova[x](y);
Ricevo però un errore di sintassi su quest'ultima riga.
Ho fatto una ricerca leggendo che effettivamente la sintassi che uso è corretta, mentre su un altro sito ho letto che in questi casi si consiglia di usare vector, ma in che modo dovrei passargli l'argomento del costruttore?
Grazie per le dritte =)
Ti stai cacciando in un bel casino, non puoi cercare una strada piu' semplice senza dover passare y?
Comunque, quello che vuoi fare si risolve con una placement new.
Devi fare una cosa di questo tipo:
class C
{
public:
C()
{
}
C(int x)
{
val = x;
}
private:
int val;
};
C* v = new C[100];
for (int i = 0; i < 100; ++i)
{
new (&v[i]) C(10); // PLACEMENT NEW
}
delete[] v;
Il costruttore di default di C fa volutamente nulla. Non e' una tecnica che ti consiglio se non sai esattamente quello che stai facendo.
Ti stai cacciando in un bel casino, non puoi cercare una strada piu' semplice senza dover passare y?
Comunque, quello che vuoi fare si risolve con una placement new.
Devi fare una cosa di questo tipo:
class C
{
public:
C()
{
}
C(int x)
{
val = x;
}
private:
int val;
};
C* v = new C[100];
for (int i = 0; i < 100; ++i)
{
new (&v[i]) C(10); // PLACEMENT NEW
}
delete[] v;
Il costruttore di default di C fa volutamente nulla. Non e' una tecnica che ti consiglio se non sai esattamente quello che stai facendo.
Mh va decisamente contro quella che era la mia idea originaria (visto che intendevo mantenere il codice molto più semplice e conciso)... penso proprio che adotterò un'altra strategia... non credevo fosse impossibile ralizzare quello che volevo fare usando solo l'operatore new :doh:
scusa ma dato che il costruttore della classe Prova ha il valore di default al parametro, che ci vuole a fare così?
class Prova
{
public:
Prova()
{
Prova(5);
}
Prova(int n)
{
...
}
};
:Prrr:
:mbe:
Nel codice in OP c'e' un valore di default, per cui chiamare esplicitamente il costruttore con un argomento non e' necessario, ma penso che l'autore intendesse il caso in cui l'argomento con cui inizializzare e' diverso da quello di default.
Mi correggo: e' codice valido ma non fa quello che vorresti.
marra11mg
22-04-2008, 10:27
Sì, questa potrebbe essere sicuramente una soluzione, ma ancora non fa esattamente al mio caso, perchè sto cercando di aggiungere una nuova funzionalità ad un programma che avevo già scritto, quindi così facendo sarei costretto a fare qualche modifica qua e là al codice di tutta la classe...
Davvero non c'è modo di richiamare un costruttore con argomenti non di default in questi casi?
Perchè dovresti modificare il codice della classe?
Quando esegui questa istruzione:
Prova** puntatore = new Prova*[numero_classi];
non fai altro che creare un array di puntatori alla classe, non le classi vere e proprie. Quello lo fai con l'istruzione contenuta all'interno del ciclo for.
Infatti li crei un oggetto alla volta col parametro che ti pare, passato al costruttore della SINGOLA classe.
Comunque, cerca di essere più chiaro, perchè dal topic, non si capisce se vuoi creare un array di classi lungo X elementi, oppure creare la classe passando 2 parametri al costruttore (in quel caso basterebbe aggiungere un nuovo costruttore alla classe stessa).
Davidino.gbr91
22-04-2008, 10:40
edit: ho sbagliato devo aprire un new topic
Perchè dovresti modificare il codice della classe?
Quando esegui questa istruzione:
Prova** puntatore = new Prova*[numero_classi];
non fai altro che creare un array di puntatori alla classe, non le classi vere e proprie. Quello lo fai con l'istruzione contenuta all'interno del ciclo for.
Infatti li crei un oggetto alla volta col parametro che ti pare, passato al costruttore della SINGOLA classe.
Comunque, cerca di essere più chiaro, perchè dal topic, non si capisce se vuoi creare un array di classi lungo X elementi, oppure creare la classe passando 2 parametri al costruttore (in quel caso basterebbe aggiungere un nuovo costruttore alla classe stessa).
Quando l'ho postato era chiaro, poi mi sono accorto di aver scritto al volo "x" e "y" senza spiegare da dove uscissero, quindi ho aggiunto quella riga su x e y scombinando tutto il senso... intendevo smeplicemente segnalare che nell'esempio le definivo in altro luogo, e che x era la lunghezza mentre y il valore con cui intendevo inizializzare gli oggetti.
Per il codice, qualche piccola modifica andrebbe fatta... ad esempio se io avevo il mio array di oggetti Prova, mi ci riferirei con array[i] mentre all'array di puntatori con *array[i] o dovrei usare l'operatore freccia... sono modifiche di piccola entità ma mi costringerebbero comunque a ritoccare quì e lì =)
Comunque grazie per tutti i consigli, alla fine è stata una scusa per snellire di molto il codice complessivo del programma, ma ancora mi sembra strano che non esista una notazione più concisa per una cosa che all'apparenza è così normale.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.