smyczki C ++ bez <łańcuch> i STL

głosy
4

Ja nie używałem C ++ bardzo wiele w przeszłości, i zostały niedawno robić dużo C #, a ja naprawdę stara się wrócić do podstaw C ++ ponownie. Jest to szczególnie trudne, ponieważ mandatów pracy, że żaden z najbardziej poręcznym C ++ konstrukty mogą być wykorzystywane, więc wszystkie ciągi muszą być char * 's, a nie ma przepisu na listach STL.

Co Obecnie próbuję zrobić, to stworzyć listę ciągów, czegoś, co zajęłoby mi w ogóle czasu przy użyciu STL lub w języku C #. Zasadniczo chcę mieć funkcji, takich jak:

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

Następnie,

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

}

lub, jeśli to C # ...

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

i zdaję sobie sprawę, że to nie działa. Wiem, że const charakter przekazywanych zmiennych (const wskaźnik i const string) sprawia, że ​​dość trudno, ale moim podstawowym problemem jest to, że ja zawsze uniknąć takiej sytuacji w przeszłości za pomocą list STL itp więc nigdy nie musiał obejść!

Przepraszam za komentarz takie trywialne pytanie, a każda pomoc będzie niezwykle ceniona!

Twoje zdrowie,

Xan

Utwórz 18/09/2008 o 12:19
źródło użytkownik
W innych językach...                            


14 odpowiedzi

głosy
5

Będę prawdopodobnie uzyskać głosowali w dół dla tej odpowiedzi, bo to naprawdę nie jest odpowiedź, ale istnieją powody, które mogłyby legitmate być unikane STL. Przy pracy w stałych environemnts gdzie pamięć lub prędkość jest premia, to czasami trudno powiedzieć, co dzieje się pod maską z STL. Tak, można napisać własne podzielników pamięci, i tak, prędkość zazwyczaj nie jest problemem, ale istnieją różnice między implementacjami STL całej platformy, a różnice te mighe być subtelne i potencjalnie wadliwy. Pamięć jest chyba moim największym problemem, gdy myśli o jej używania. Ja też pracuję w firmie gry, a przez długi czas. Pamięć jest cenna i jak używamy musi być tighly kontrolowane. Chyba, że ​​już na tej drodze, koncepcja ta nie może mieć sens, ale to prawda. Zdajemy sobie pozwolić na wykorzystanie STL w narzędziach (poza kodu gry) l, ale to zabronione wewnątrz rzeczywistej grze. Jednym innych związanych problemem jest rozmiar kodu. Jestem nieco niepewni, ile STL może przyczynić się do rozmiaru pliku wykonywalnego, ale widzieliśmy znaczący wzrost w wielkości kodu przy użyciu STL. Nawet jeśli plik wykonywalny jest „tylko” 2M większe, to 2M mniej RAM na coś innego do gry.

STL jest ładny na pewno. Ale to może być wykorzystywane przez programistów, którzy nie wiedzą, co robią. To nie jest zamierzone, ale może ona dostarczyć nieprzyjemnych niespodzianek, jeśli nie chcesz je zobaczyć (ponownie, problemy z wydajnością uwędzić i pamięć)

Jestem pewien, że jesteś blisko ze swoim rozwiązaniem.

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);
}

Być może nie chcesz używać strdup. To jest po prostu przykładem, w jaki sposób przechowywać nazwę nadaną Twój przykład. Może chcesz się upewnić, że albo nie chce przydzielić miejsca dla nowej nazwy siebie, lub użyć innej konstrukt pamięci, które mogą być już dostępne w aplikacji.

I proszę, nie pisz do klasy String. Mam zajęcia odbywają się jako ciąg chyba najgorszy przykład jak nie należy ponownie inżynier podstawową konstrukcję C w C ++. Tak, klasa String można ukryć wiele ładne szczegóły z wami, ale to pamięć wzory użytkowe są straszne, a te nie dobrze pasuje do konsoli (tj PS3 lub 360, etc) środowisko. Około 8 lat temu zrobiliśmy ten sam czas. 200000+ alokacje pamięci zanim trafiliśmy do menu głównego. Pamięć strasznie fragmentaryczne i nie mogliśmy dostać reszta gry, aby zmieścić się w ustalonym środowisku. Wylądowaliśmy zgrywania go.

Klasa jest wielki projekt dla niektórych rzeczy, ale to nie jest jeden z nich. Jest to opinia, ale jest ona oparta na rzeczywistych doświadczeniach światowej.

Odpowiedział 18/09/2008 o 13:17
źródło użytkownik

głosy
5

Jeśli przenośność jest problemem, może chcesz sprawdzić STLport .

Odpowiedział 18/09/2008 o 12:46
źródło użytkownik

głosy
5

prawdopodobnie będziesz musiał użyć strcmp aby sprawdzić, czy ciąg jest już zapisane:

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

Następnie, jeśli naprawdę trzeba przechowywać kopię napisu, następnie trzeba będzie przeznaczyć bufor i skopiować znaki ciągu.

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

Nie wspominając, czy wejście jest NULL rozwiązana - jeśli nie, to potrzebna jest dodatkowa opieka i strcmp / strcpy nie będą odpowiednie.

Odpowiedział 18/09/2008 o 12:28
źródło użytkownik

głosy
3

Dlaczego nie można użyć STL?

W każdym razie, chciałbym zaproponować, aby zaimplementować proste klasy String i lista szablonów własnych. W ten sposób można korzystać z tych samych technik jak zwykle i utrzymać wskaźnik pamięci zarządzania i ogranicza się do tych klas. Jeśli naśladować STL, byłoby jeszcze lepiej.

Odpowiedział 18/09/2008 o 12:29
źródło użytkownik

głosy
2

Jeśli naprawdę nie można użyć STL (i żałuję, wierząc, że to prawda, kiedy byłem w branży gier), to nie można tworzyć własne klasy String? Najbardziej podstawowe klasy string będzie przydzielić pamięci na budowę i przydziału i obsłużyć Usuń w destructor. Później można dodać kolejne funkcje, jak jest to potrzebne. Całkowicie przenośny i bardzo łatwe do napisania i testów jednostkowych.

Odpowiedział 18/09/2008 o 12:56
źródło użytkownik

głosy
1

Mogę zrozumieć, dlaczego nie można użyć STL - większość nie uwędzić kod strasznie. Jednakże istnieją implementacje dla programistów gier przez programistów gier - RDESTL jest jednym z takich bibliotek.

Odpowiedział 18/09/2008 o 13:13
źródło użytkownik

głosy
1

Za pomocą:

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

będzie można przypisać const * char constdo elementu tablicy.

Tak z ciekawości, dlaczego „mandaty pracy, że żaden z najbardziej poręcznym C ++ konstrukty mogą być używane”?

Odpowiedział 18/09/2008 o 12:29
źródło użytkownik

głosy
1

Praca z char * wymaga do pracy z funkcji C. W twoim przypadku, to, czego naprawdę potrzebujesz, to skopiować sznurki wokół. Aby pomóc, masz funkcję strndup. Wtedy będziesz musiał napisać coś takiego:

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

Ten kod przypuszczać macierzy jest wystarczająco duża.

Oczywiście, najlepiej byłoby bardzo poprawnie zaimplementować własną ciąg i tablicę i listy ... lub przekonać swojego szefa STL nie jest już zły!

Odpowiedział 18/09/2008 o 12:29
źródło użytkownik

głosy
1

Edit: Chyba zrozumiał swoje pytanie. Nie ma problemu constness w tym kodzie jestem świadomy.

Robię to z głowy, ale powinna być o prawo:

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;
    }
}
Odpowiedział 18/09/2008 o 12:26
źródło użytkownik

głosy
0

Jest to wyraźny przypadek dostać się toczyć własną rękę. I zrobić to samo dla klasy wektorowych.

  • Zrobić z programowaniem testu pierwszego.
  • Nie komplikuj.

Uniknąć odniesienia liczenia bufor ciąg jeśli jesteś w środowisku MT.

Odpowiedział 19/09/2008 o 18:29
źródło użytkownik

głosy
0

Użyłem tej klasy String lat.

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

Zapewnia on praktycznie wszystkie funkcje ciąg STL ale jest zaimplementowany jako prawdziwej klasy nie szablon i nie używa STL.

Odpowiedział 19/09/2008 o 00:08
źródło użytkownik

głosy
0

Poprawność const const poprawności jest nadal, niezależnie od tego, czy skorzystać z STL czy nie. Wierzę, że to, czego szukasz jest, aby registeredNames const char **tak, że przypisanie do registeredNames[i](co jest const char *) działa.

Co więcej, jest to naprawdę to, co chcesz robić? Wydaje się, że wykonanie kopii napisu jest chyba bardziej odpowiednie.

Ponadto nadal, nie należy myśleć o przechowywanie tego w wykazie danej operacji robisz na nim, zestaw będzie lepiej.

Odpowiedział 18/09/2008 o 14:37
źródło użytkownik

głosy
0

Wszystkie podejścia je są ważne, chodzi mi o to, czy sposób C # robi to jest atrakcyjne replikować go, tworzyć własne klasy / interfejsy do przedstawienia tej samej abstrakcji, czyli prosty związane klasa lista metod Zawiera dodawanie, korzystając z przykładowego kodu dostarczonego przez innych odpowiedzi to powinno być stosunkowo proste.

Jednym z wielkich rzeczy na temat C ++ jest na ogół można je wyglądać i zachowywać się tak, jak chcesz, jeśli inny język ma wielką realizację czegoś zazwyczaj można odtworzyć go.

Odpowiedział 18/09/2008 o 14:18
źródło użytkownik

głosy
0

Jeśli nie martwisz się o konwencjach i po prostu chcą, aby otrzymać pracę użycia realloc. Robię tego rodzaju rzeczy dla list przez cały czas, to idzie mniej więcej tak:

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)
}

Jest więcej można zrobić, na przykład tylko realloc każdym razem podwaja wielkość listy funkcje do usuwania pozycji z listy przez indeks lub poprzez sprawdzenie równości uczynić klasę szablonu do obsługi list itp ... (mam jeden napisałem wieki temu i zawsze stosować się ... ale niestety jestem w pracy i nie można po prostu skopiować i wkleić go tutaj). Szczerze mówiąc jednak, to prawdopodobnie nie przewyższa równowartość STL, chociaż może się równać jego wydajność, jeśli nie mnóstwo pracy lub mają szczególnie słabą realizację STL.

Irytująco C ++ jest bez operator odnowić / rozmiaru zastąpić realloc, co byłoby bardzo przydatne.

Aha, i przepraszam, jeśli mój kod błędu jeździł, tylko wyciągnął go z pamięci.

Odpowiedział 18/09/2008 o 13:37
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more