Autor Wątek: [lib] Dziwne zachowenie przy inicjalizacji zmiennych w konstruktorze  (Przeczytany 689 razy)

Offline Tobix10

  • Użytkownik

# Maj 15, 2009, 18:50:56
Napisałem sobie klasę StringInput podobną do tej z tutoriala LazyFoo i dołączyłem do własnej biblioteki statycznej. Teraz w celu sprawdzenia czy wszystko działa utworzyłem nowy projekt i dodałem do opcji linkera moją bibliotekę, potrzebne nagłówki w kodzie itp.

Tak wygląda definicja klasy, dodałem do niej obiekt ofstream, ponieważ chciałem zapisać operacje z funkcji LoadInput do pliku i sprawdzić czy one w ogóle działają, gdyż tekst jest cały czas pusty.
#ifndef STRINGINPUT_H
#define STRINGINPUT_H

#include <SDL.h>
#include <string>
#include <fstream>

class StringInput
{
public:
StringInput(int max);
~StringInput();

void LoadInput(SDL_Event *Ev);
std::string GetText() { return strText; }
void EraseText() { strText = ""; }

private:
int iMaxLength;
std::string strText;
std::ofstream a;
};
#endif
a tak definicje funkcji
#include "StringInput.h"

StringInput::StringInput(int max) : iMaxLength(max), strText("")
{a.open("C:\\plik.txt", std::ios::out); }
StringInput::~StringInput()
{}

void StringInput::LoadInput(SDL_Event *Ev)
{
if(Ev->type == SDL_KEYDOWN)
{
if(strText.length() <= iMaxLength) //jeżeli jeszcze nie pobrano maksymalnej liczby znaków
{
if(Ev->key.keysym.sym == SDLK_SPACE)
{
strText += ' ';
a << "Spacja" << strText << "spacja";
}
else if((Ev->key.keysym.sym >= SDLK_0) && (Ev->key.keysym.sym <= SDLK_9))
{
strText += static_cast<char>(Ev->key.keysym.sym);
a << "Cyfra " << strText;
}
else if((Ev->key.keysym.sym >= SDLK_a) && (Ev->key.keysym.sym <= SDLK_z))
{
strText += static_cast<char>(Ev->key.keysym.sym);
a << "Litera " << strText;
}

/* jeżeli wciśnięto backspace, a tekst nie jest pusty, usuń ostatni znak */
if((Ev->key.keysym.sym == SDLK_BACKSPACE) && strText.length())
{
strText.erase(--strText.end());
a << "Usuwam " << strText;
}
a << std::endl;
}
}
}
Na początku jak jeszcze klasa była pozbawiona obiektu ofstream w liście inicjalizacyjnej konstruktora na pierwszym miejscu było strText(""), a na drugim iMaxLength(max). Wtedy podglądałem zmienne w debuggerze i o dziwo iMaxLength nie była inicjalizowana wartością jaką podałem(miała wartość -87........).
Zamieniłem miejscami te zmienne i w klasie i w konstruktorze i wszystko było ok.
Teraz jak dodałem ten obiekt ofstream i otwarcie pliku w konstruktorze to strText = <Bad ptr>. Wytłumaczy mi ktoś o co chodzi ?

I też nie wiem dlaczego nie przypisuje mi klikanych liter na klawiaturze do zmiennej strText. Dodam, że jak przeniosłem całą klasę i jej definicje bezpośrednio do pliku cpp, w którym testowałem bibliotekę to wszytko działało prawidłowo.

Pracuje na MS Visual C++ 08 EE
« Ostatnia zmiana: Maj 15, 2009, 18:58:05 wysłana przez Tobix10 »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline .:NOXY:.

  • Użytkownik
    • Profil

# Maj 15, 2009, 20:05:27
Po pierwsze oducz się czyścić std::string na zasadzie [ cos = "" ] bo to zly anwyk po to jest funkcja clear(); wiec w twoim przypadku to bedzie: strText.clear();

Po drugie:

StringInput::StringInput(int max) : iMaxLength(max)
{
     strText.clear();
     a.open("C:\\plik.txt", std::fstream:out);  //standard moj drogi nie ios tylko fstream
     if(!a)
     {
          std::cout<<"ladna kupa :D\n"; //radze sprawdzac czy sie wogole stworzyl
     }

}


ogolnie VC ma jakies dziwne opory z fstram ofstream ifstream itp jezeli sa w klasie mialem te same problemy ;p oglnie radze sprwadzać co tak naprawde sie dzieje z strumieniem bo on moze powodowac bledy

Offline Tobix10

  • Użytkownik

# Maj 15, 2009, 20:31:13
fstream zamiast ios to pierwsze widzę ;) uczyłem się z Symfonii i tam było ios, dlatego tak piszę, ale spojrzałem na cppreference i faktycznie jest fstream. Trzeba zmienić nawyki :D.

Plik się tworzy, ale jest pusty bo string nie może się utworzyć. Jest Bad ptr i na koniec programu wywala błąd naruszenia pamięci. Nie wiem dlaczego tylko na końcu skoro przez cały czas ten string jest używany. Już wcześniej powinien być błąd.

Już wszystko działa poprawnie. Widocznie problem leżał w tym, że używałem biblioteki w wersji release a program był w debug.
« Ostatnia zmiana: Maj 15, 2009, 20:41:38 wysłana przez Tobix10 »

Offline Aithne

  • Użytkownik

# Maj 16, 2009, 01:51:39
.:NOXY:., z łaski swojej, nie głoś herezji. Tryby otwarcia są zdefiniowane w typie std::uwaga, uwaga...ios_base::openmode. Wersja z użyciem std::ios::* jest jak najbardziej poprawna (dziedziczenie, misiu!).

Offline .:NOXY:.

  • Użytkownik
    • Profil

# Maj 16, 2009, 13:31:25
niby poprawna ale GCC tego nie toleruje :) musialem caly projekt przerabiac jak go pod code block dawalem daltego oszczedzam sobie takich praktyk z misiowaniem :p bo o dziwo powinno akceptowac ale sie nie kompuluje :]

Offline Aithne

  • Użytkownik

# Maj 16, 2009, 15:36:21
Standardu nie interesują błędy kompilatorów. A tak w ogóle... Chyba jakieś dziwne GCC masz.