Domanda

Non ho usato il C++ molto in passato, e di recente hanno fatto un sacco di C#, e sto davvero fatica a tornare fondamenti di C++ di nuovo.Questo è particolarmente difficile in quanto il lavoro di mandati che nessuno di più pratico di C++ costrutti possono essere utilizzati, in modo che tutte le stringhe devono essere di tipo char *'s, e non vi è alcuna disposizione per STL liste.

Quello che attualmente sto cercando di fare è creare una lista di stringhe, qualcosa che mi avrebbe portato nessun momento a tutti STL o in C#.Fondamentalmente voglio avere una funzione del tipo:

char **registeredNames = new char*[numberOfNames];

Quindi,

RegisterName(const * char const name, const int length)
{
    //loop to see if name already registered snipped
    if(notFound)
    {
        registeredNames[lastIndex++] = name;
    }

}

o, se è stato il C#...

if(!registeredNames.Contains(name))
{
    registeredNames.Add(name);
}

e mi rendo conto che non funziona.So che il const natura del passato variabili (un puntatore const e un const string) rende piuttosto difficile, ma il mio problema di base è che ho sempre evitato questa situazione in passato utilizzando STL list etc.quindi non ho mai dovuto lavorare tutto!!!

È stato utile?

Soluzione

Avrete probabilmente bisogno di usare strcmp per vedere se la stringa è già memorizzato:

for (int index=0; index<=lastIndex; index++)
{
  if (strcmp(registeredNames[index], name) == 0)
  {
    return; // Already registered
  }
}

Quindi se si ha realmente bisogno di conservare una copia della stringa, quindi è necessario allocare un buffer e copiare i personaggi sopra.

char* nameCopy = malloc(length+1);
strcpy(nameCopy, name);
registeredNames[lastIndex++] = nameCopy;

Lei non ha menzionato se il vostro ingresso di terminazione NULL - se non, allora la cura supplementare è necessaria, e strcmp/strcpy non essere adatto.

Altri suggerimenti

Ci sono motivi legittimi, STL potrebbe essere evitato.Quando si lavora in fissa ambienti in cui la memoria o la velocità di un premio, a volte è difficile dire che cosa sta succedendo sotto il cofano con il STL.Sì, è possibile scrivere la propria memoria i contatori, e sì, la velocità in genere non è un problema, ma ci sono differenze tra STL implementazioni delle piattaforme, e tali differenze mighe essere sottile e potenzialmente buggy.La memoria è forse la mia più grande preoccupazione quando si parla di utilizzo.

La memoria è preziosa, e come le usiamo deve essere strettamente controllata.A meno che non hai già percorso questa strada, questo concetto potrebbe non avere senso, ma è vero.Ci permettono di STL utilizzo di strumenti (al di fuori del codice del gioco), ma è proibito all'interno del gioco vero e proprio.Un altro problema è la dimensione del codice.Io sono un po ' incerto di quanto STL può contribuire a dimensione del file eseguibile, ma abbiamo visto un aumento delle dimensioni del codice quando si utilizza STL.Anche se l'eseguibile è "solo" 2M più grande, che è 2M meno RAM per qualcosa di diverso per il vostro gioco.

STL è bello di sicuro.Ma può essere abusato da programmatori che non sanno quello che fanno.Non è intenzionale, ma è in grado di fornire brutte sorprese quando non si ha voglia di vedere (di nuovo, di memoria bloat e problemi di prestazioni)

Sono sicuro che vi sono vicino con la tua soluzione.

for ( i = 0; i < lastIndex; i++ ) {
    if ( !strcmp(&registeredNames[i], name ) {
        break;    // name was found
    }
}
if ( i == lastIndex ) {
    // name was not found in the registeredNames list
    registeredNames[lastIndex++] = strdup(name);
}

Si potrebbe non voler utilizzare strdup.Questo è semplicemente un esempio di come memorizzare il nome dato l'esempio.Si potrebbe desiderare di assicurarsi che sia non si desidera allocare lo spazio per il nuovo nome, o usare qualche altra memoria costruire che possono essere già disponibili nell'app.

E per favore, non scrivere una stringa di classe.Ho tenuto fino stringa classi come forse il peggior esempio di come non ri-progettare una base C di costruire in C++.Sì, la classe string può nascondere un sacco di nifty dettagli da voi, ma è la memoria di modelli di utilizzo sono terribili, e quelli che non si adattano bene in una console (es.ps3 o 360, ecc) ambiente.Circa 8 anni fa abbiamo fatto lo stesso tempo.200000+ allocazioni di memoria prima di colpire il menu principale.La memoria era molto frammentato e non siamo riusciti a ottenere il resto del gioco per misura fissa ambiente.Si conclude strappa fuori.

Design di classe, è ottimo per alcune cose, ma questo non è uno di loro.Questa è un'opinione, ma si basa sulla esperienza del mondo reale.

Se la portabilità è un problema, si potrebbe desiderare di check-out STLport.

Perché non puoi usare il STL?

Comunque, vorrei suggerire di implementare una semplice stringa di classe e di modelli di elenco dei vostri propri.In questo modo è possibile utilizzare le stesse tecniche come si farebbe normalmente e mantenere il puntatore e la gestione della memoria limitato alle classi.Se si imitano le STL, sarebbe ancora meglio.

Se davvero non si può utilizzare stl (e mi rammarico del fatto credere che era vero quando ero nel settore dei giochi) quindi non puoi creare la tua stringa di classe?La maggior parte di base della classe string allocazione di memoria per la costruzione e la cessione, e di gestire l'eliminazione nel distruttore.Poi si potrebbe aggiungere ulteriori funzionalità come avete bisogno.Completamente portatile e molto facile da scrivere e test di unità.

Lavorare con char* richiede di lavorare con le funzioni C.Nel tuo caso, che cosa si ha realmente bisogno è quello di copiare le stringhe attorno.Per aiutarvi, si ha la strndup funzione.Allora devi scrivere qualcosa come:

void RegisterName(const char* name)
{
  // loop to see if name already registered snipped
  if(notFound)
  {
    registerNames[lastIndex++] = stdndup(name, MAX_STRING_LENGTH);
  }
}

Questo codice supponiamo che la matrice a disposizione è abbastanza grande.

Naturalmente, la cosa migliore sarebbe di implementare correttamente il proprio stringhe e array e un elenco ...o per convincere il tuo capo il STL non è il male più !

Edit:Credo che ho frainteso la tua domanda.Non c'è constness ' problema in questo codice sono a conoscenza di.

Sto facendo tutto questo dalla mia testa, ma dovrebbe essere circa la destra:

static int lastIndex = 0;
static char **registeredNames = new char*[numberOfNames];

void RegisterName(const * char const name)
{
    bool found = false;
    //loop to see if name already registered snipped
    for (int i = 0; i < lastIndex; i++)
    {
        if (strcmp(name, registeredNames[i] == 0))
        {
            found = true;
            break;
        }
    }

    if (!found)
    {
        registeredNames[lastIndex++] = name;
    }
}

Posso capire perché non è possibile utilizzare STL - la maggior parte fanno gonfiare il tuo codice terribilmente.Tuttavia ci sono implementazioni per i giochi programmatori di giochi programmatori - RDESTL è una biblioteca.

Utilizzo:

const char **registeredNames = new const char * [numberOfNames];

vi permetterà di assegnare un const * char const a un elemento dell'array.

Solo per curiosità, perché "il lavoro impone che nessuno di più pratico di C++ costrutti possono essere utilizzati"?

Tutti gli approcci proposti sono validi, il mio punto è se il modo in C# non è attraente replicare, creare le proprie classi/interfacce per presentare la stessa astrazione, cioèun semplice elenco collegato di classe con metodi Contiene e Aggiungere, utilizzando il codice di esempio fornito da altre risposte di questo dovrebbe essere relativamente semplice.

Una delle grandi cose circa il C++ è, generalmente, si può fare da guardare e agire nel modo desiderato, se un'altra lingua è una grande implementazione di qualcosa di solito è possibile riprodurlo.

Ho usato questa Stringa di classe per anni.

http://www.robertnz.net/string.htm

Esso fornisce praticamente tutte le caratteristiche del STL stringa, ma è implementato come una vera classe non un modello e non fa uso di STL.

Questo è un chiaro caso di arrivare a rotolare il vostro proprio.E fare lo stesso per una classe vector.

  • Farlo con la prima i test di programmazione.
  • Mantenere le cose semplici.

Evitare di riferimento per il conteggio del buffer di stringa, se siete in MT ambiente.

Se non si è preoccupato di convenzioni e vogliono solo ottenere il lavoro fatto uso di realloc.Faccio questo genere di cose per le liste di tutti i tempi, va qualcosa come questo:

T** list = 0;
unsigned int length = 0;

T* AddItem(T Item)
{
 list = realloc(list, sizeof(T)*(length+1));
 if(!list) return 0;
 list[length] = new T(Item);
 ++length;
 return list[length];
}

void CleanupList()
{
 for(unsigned int i = 0; i < length; ++i)
 {
  delete item[i];
 }
 free(list)
}

C'è di più si può fare, ad esempiosolo realloc ogni volta che l'elenco di dimensioni doppie, funzioni per la rimozione di elementi dalla lista per l'indice o il controllo di uguaglianza, di fare un modello di classe per la gestione di elenchi, ecc...(Ne ho uno che ho scritto tempo fa e utilizzare sempre me stesso...ma purtroppo sono al lavoro e non si può semplicemente copiare e incollare qui).Per essere onesti, però, questo probabilmente non superare il STL equivalente, anche se può eguagliare il suo rendimento se si fanno un sacco di lavoro o che hanno un particolare di scarsa attuazione di STL.

Fastidiosamente C++ è senza un operatore rinnovare/ridimensiona a sostituire realloc, il che sarebbe molto utile.

Oh, e mi scuso se il mio codice di errore sotto la sella, ho appena tirato fuori dalla memoria.

const la correttezza non è ancora const correttezza indipendentemente dal fatto che si utilizza il STL o non.Credo che quello che stai cercando di fare un registeredNames const char ** in modo che l'assegnazione di registeredNames[i] (che è un const char *) funziona.

Inoltre, è davvero questo quello che vuoi fare?Sembra che la creazione di una copia della stringa è probabilmente più appropriato.

Inoltre ancora, non si deve pensare circa la conservazione di questo in un elenco fornito l'operazione che si sta facendo su di esso, un insieme sarebbe meglio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top