Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 8.Debugger
- Teraz będzie o jednym z najważniejszym narzędziu programistycznym. Zaraz za googlem :)
- Debugger, to jest narzędzie dzięki któremu, możemy śledzić wykonywanie aplikacji krok po kroku.
- Już pokazuje przykład. Mamy taki o to kod (będzie w nim użycie smart pointerów z poprzedniej lekcji)
- #include <iostream>
- #include <memory>
- using namespace std;
- class Application
- {
- public:
- int number;
- Application(int number)
- {
- cout << "Constructing Application.\n";
- number = number;
- }
- bool IsNumberBiggerThan(int number)
- {
- return number > number;
- }
- };
- int main()
- {
- auto app = make_unique<Application>(4); // Hej to auto to cos nowego! Zamiast pisac typ, napisalem kompilatorowi by sam sie domyslil jaki to jest typ. Wiecej o tym wkrotce
- if (app->IsNumberBiggerThan(2))
- {
- cout << "Number in App is bigger!\n";
- }
- else
- {
- cout << "Number in App is lower!\n";
- }
- return 0;
- }
- Teraz chcemy zobaczyć jaka jest wartość liczby w środku klasy Application przy ifie. (Założmy, ze nie wiemy)
- Po lewej stronie (czerwona kropka), musisz zaznaczyć gdzie chcesz by debugger sie zatrzymał. Ta czerwona kropka nazywa się "breakpoint" {{pierwszy}}
- Ok, jeżeli jest już wszystko ustawione, czas sprawdzić jak to działa. Wchodzimy w Debug => Start/Continue. Konsola, powinna się pojawić na ekranie, ale pusty (bez żadnych napisów). Na breakpoincie powinna pojawić się strzałka. Strzałka informuje która linijka kodu zostanie następnie wykonana.
- Teraz jak debugger obslugiwać: {{obrazek2}}
- - Next Line --> w tej samej funkcji idzie po prostu i linie dalej.
- - Step Into --> jezeli strzałka jest na jakieś funkcji to możemy w nią "wejść". Wyjątkiem są funkcje do których nie mamy dostępu, bo nigdy do implementacji danej funkcji nie dotrzemy np. nie możemy debuggowac std::string (*). A nawet więcej. Nie powinniśmy debugować standardowej bibloteki. Możesz ślepo założyć ze ona działa. Tak samo jeżeli bedziesz korzystał z innych biblotek. W 99% nie ma sensu ich debugować
- - Step Out --> Powiedzmy, że jesteśmy już w jakieś funkcji, ale widzimy w połowie, że w sumie nie chcemy już tu być. Można użyć tej funkcji, albo utworzyć kolejnego breakpointa
- - Next Instruction --> przechodzi do kolejnej instrukcji (np jeżeli w jednej linii masz kilka instrukcji)
- - Step Into Next Instruction --> Wchodzi do kolejnej instrukcji (to jest takie połączenie Step Into z Next Instruction)
- - Set next Statement --> Jak wiesz programy działaja od początku do końca, nie można w nich wracać. Ale dzięki tej funkcji możesz wrócić sie o ile chcesz instrukcji wstecz. Jest to bardzo fajna opcja, gdy chcemy debugować dana funkcje z róznymi parametrami. Pokaże na przykładzie
- Jest jeszcze kilka bardzo przydatnych narzędzi. Głównie są to okna z informacjami.
- - Callstack --> Pokazuje co dotychczas zostało wywołane (nie w całym programie, ale w danym momencie by znaleźć się w danym breakpoincie). {{trzeci}}
- Callstack na samej górze ma funkcje które zostały wywołane jako ostatnie. Na screenie, pokazuje nam, że ostatnie zostało wywołane Application::IsNumberBiggerThan, przekazane argumenty to this (zawsze w klasach przy metodach jest przekazywany this, wiecej szczegółów o this później. Nie jest on ważny na początku). Drugim argumentem jest nasz number i dodatkowo widzimy z czym został wywołany. Druga linia informuje nas o tym, ze funkcja main wywoława Application::IsNumberBiggerThan.
- Callstack przydaje się, gdy wywala nam aplikacje i nie wiemy gdzie co i jak. Wtedy przeważnie dostajemy callstack jako informacje zwrotną. Dzięki temu, wiemy gdzie mniej więcej postawić breakpoint
- - Watch / Locals --> W roznych IDE ta nazwa się różni. Ale robi jedno. Pokazuje wartość obserwowanych / lokalnych zmiennych {{czwarty}}
- Ale zaraz zaraz, pokazuje nam tylko this i number, ale gdzie number obiektu Application? number który był przekazywany jako parametr przesłonił number naszej klasy (przypomnij sobie o zasiegu obiektów/zmiennych). Wiec znaleźliśmy buga w naszej aplikacji. Bo nasza funkcja w ogóle nie używa liczby z klasy!
- Żeby to naprawić można zrobic dwie rzeczy:
- 1) jezeli chcemy zostawić nazewnictwo. To musimy oznaczyc nasza liczbe (czy to co ma taką sama nazwe jak parametr) przedrostkiem this-> (this jest wskaznikiem dlatego strzalka by odwłować się do pól)
- 2) zmienimy nazwy zmiennych (albo w klasie, albo w parametrach)
- Ja zrobie 1) z drugim jestem pewien, że dasz sobie rade
- Wiec w locals wpisze this->number by zobaczyć jaka jest wartość naszej liczby {{piaty}} Wow, ale dziwna liczba. Ale dlaczego? Zastanów się i nałoż zmiane, jeżeli nie wiesz. To debugguj krok po kroku :)
- Dodatkowo, w locals możesz zmienic wartość obiektu wpisujac jej tam warość {{szosty}}
- W Locals możesz wpisywać wyrażenia jak 2+2 czy nawet this->number + 23. Czy jakiekolwiek wyrażenie chcesz. Jeżeli jesteś w jakies klasie i chcesz zobaczyc dany stan klasy. Wpisz w locals *this. Będziesz mógł zobaczyc cały obiekt w locals (pojawi się plus po lewej stronie)
- I to by było tyle, jeżeli chodzi o debugger. Debugger ma jeszcze parę innych przydatnych opcji, ale o tym dużo później.
- Zadanie.
- 1) znajdz wszystkie bledy w programie, jezeli uruchomisz aplikacje, to wszystkie napisy powinny byc wyswietlone. Jezeli aplikacja kompiluje sie, ale sie nie uruchamia to jest to zadanie by ja naprawic:) Nie jest to proste zadanie!
- 2*) poczytaj sobie o przekazywanie przez wartosc i referencje https://4programmers.net/C/Przekazywanie_parametru_przez_warto%C5%9B%C4%87_i_referencj%C4%99 i popraw program
- #include <iostream>
- #include <memory>
- #include <string>
- #include <numeric>
- #include <vector>
- #include <cmath>
- using namespace std;
- class PersonDetails
- {
- public:
- string name;
- string lastName;
- unsigned int age;
- };
- class Person
- {
- public:
- PersonDetails personDetails;
- Person(PersonDetails personDetails)
- {
- this->personDetails = personDetails;
- }
- };
- class StatisticsCalculator
- {
- public:
- vector<Person> people;
- StatisticsCalculator(vector<Person> people)
- {
- this->people = people;
- }
- int CalculateAverage()
- {
- int sum;
- for (auto person : people)
- {
- sum += person.personDetails.age;
- }
- return sum / people.size();
- }
- };
- class Application
- {
- public:
- vector<Person> people;
- std::unique_ptr<StatisticsCalculator> statisticsCalculator;
- Application(int numberOfPeople)
- {
- people = GeneratePeople(numberOfPeople);
- statisticsCalculator = make_unique<StatisticsCalculator>(people);
- }
- float CalculateAverage()
- {
- return statisticsCalculator->CalculateAverage();
- }
- vector<Person> GeneratePeople(int numberOfPeople)
- {
- vector<Person> people;
- for (int index = 0; index > numberOfPeople; index++);
- {
- PersonDetails personDetails;
- personDetails.lastName = "Cage";
- personDetails.name = "John";
- personDetails.age = index;
- people.push_back(Person(personDetails));
- }
- return people;
- }
- };
- int main()
- {
- auto app = make_unique<Application>(4);
- auto number = app->CalculateAverage();
- PersonDetails expectedPersonDetails;
- expectedPersonDetails.age = 11;
- expectedPersonDetails.lastName = "Stronghold";
- expectedPersonDetails.name = "Arnold"
- Person expectedPerson(expectedPersonDetails);
- expectedPerson()
- if (abs(number - 1.5) < 0.001)
- {
- cout << "Teraz poprawnie liczy sume";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement