shoq Opublikowano 6 Sierpnia 2009 Zgłoś Opublikowano 6 Sierpnia 2009 (edytowane) Robię sobie ćwiczenia do rozdziałów z książki Thinking in C++ i mam takie zadanko: W pliku nagłówkowym utwórz klasę Mirror, zawierająca dwie dane składowe - wskaźnik do obiektu klasy Mirror oraz składową typu bool. Utwórz dwa konstruktory. Konstruktor domyślny powinien inicjalizować składową typu bool wartością true,a wskaźnik do obiektu klasy Mirror - wartością zerową. Drugi konstruktor powinien pobierać jako argument wskaźnik do obiektu klasy Mirror, a następnie przypisywać go wskaźnikowi zawartemu w klasie, natomiast składową typu bool - inicjalizować wartością false. Dodaj funkcję składową test() - jeżeli wartość wskaźnika zawartego w obiekcie jest niezerowa, to funkcja ta powinna zwrócić wartość zwracaną przez funkcję test() wykonaną za pośrednictwem tego wskaźnika. Jeżeli natomiast wartość wskaźnika jest zerowa to funkcja powinna zwrócić wartość składowej typu bool. Następnie utwórz 5 plików cpp w taki sposób, by do każdego z nich został dołączony plik nagłówkowy klasy Mirror. W pierwszym pliku cpp, za pomocą konstruktora utwórz globalny obiekt klasy Mirror. W drugim pliku, za pomocą specyfikatora extern, zadeklaruj obiekt znajdujący się w pierwszym pliku, a także przy użyciu konstruktora pobierającego wskaźnik do pierwszego obiektu, zdefiniuj globalny obiekt klasy Mirror. Kontynuuj taki sposób tworzenia kolejnych obiektów, aż do ostatniego pliku, zawierającego również globalną definicje obiektu. W znajdującej się w tym pliku funkcji main() wywołaj funkcję test() i sprawdź wyświetlony przez tę funkcję wynik. Jeżeli wynikiem tym jest true, dowiedz się, w jaki sposób można zmienić kolejność łącznia plików przez program łączacy i zmieniaj ją dopóty, dopóki wynikiem zwracanym przez funkcję będzie false. Problem jest taki, że funkcja zwraca mi wartość true, a nie wiem jak zmienić kolejność łączenia plików. Używam Visual Studio 2008 lub g++ pod linuxem. Jakby mi ktoś powiedział jak zmienić kolejność łączenia plików przez linker pod którymkolwiek z tych dwóch kompilatorów to byłbym wdzięczny. Szukałem na google, ale nie mogłem nic znaleźć. Wydaje mi się też (choć to może być błędne moje rozumowanie), że funkcja test() zawsze będzie zwracać wartość true bo funkcja test() jest wywoływana dopóki wskaźnik w składowej klasy Mirror nie jest ustawiony na 0. Poniżej zamieszczam swoje pliki: mirror.h #ifndef MIRROR_H#define MIRROR_H#include <iostream>class Mirror { Mirror* wsk; bool is;public: Mirror() : wsk(NULL), is(true) {} Mirror(Mirror* src) : is(false) {wsk=src;} int out() const { return (int)wsk; } bool test() const { if(wsk!=NULL) { std::cout << "wsk->test()" << std::endl; return wsk->test(); } else return is; }};#endif plik1.cpp #include <iostream>#include "mirror.h"Mirror V1; plik2.cpp #include <iostream>#include "mirror.h"extern Mirror V1;Mirror V2(&V1); plik3.cpp #include <iostream>#include "mirror.h"extern Mirror V2;Mirror V3(&V2); plik4.cpp #include <iostream>#include "mirror.h"extern Mirror V3;Mirror V4(&V3); plik5.cpp #include <iostream>#include "mirror.h"using namespace std;extern Mirror V4;Mirror V5(&V4);int _tmain(int argc, _TCHAR* argv[]){ cout << "V5.test() = " << V5.test() << endl;// system("PAUSE"); return 0;} Edytowane 9 Sierpnia 2009 przez luqash Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
danrok Opublikowano 8 Sierpnia 2009 Zgłoś Opublikowano 8 Sierpnia 2009 Hmm. Każdy *wsk pokazuje na poprzedni element. Nie ma takiego ułożenia, żeby funkcja nie zwróciła true. Mogłoby to nastąpić, gdybyś V1 stworzył za pomocą konstruktora parametrycznego, jednak musiałbyś podać znowu inny obiekt. Dobrze to zrobiłeś, chyba zadanie jest jakieś dziwne ;) Wskaźnika się nie ustawia na 0, tylko na NULL, to różnica ;) W ogóle ta cała zabawa z extern, nie wiadomo po co. Wszystko sprowadza się do takiego wywołania: Mirror V1; Mirror V2(&V1); ... Jeśli ktoś twierdzi inaczej, niech napisze ;) Pozdrawiam. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Drainer Opublikowano 8 Sierpnia 2009 Zgłoś Opublikowano 8 Sierpnia 2009 Wskaźnika się nie ustawia na 0, tylko na NULL, to różnica ;)czym sie rozni 0 od null ? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
danrok Opublikowano 8 Sierpnia 2009 Zgłoś Opublikowano 8 Sierpnia 2009 Wydawało mi się, że zero to skalar i można przypisać do zmiennej, a NULL do wskaźnika, ale sprawdzałem później i okazuje się, że wsk = 0; też działa. Wydawało mi się, że się różni czymś. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Drainer Opublikowano 8 Sierpnia 2009 Zgłoś Opublikowano 8 Sierpnia 2009 (edytowane) ... Kontynuuj taki sposób tworzenia kolejnych obiektów, aż do ostatniego pliku, zawierającego również globalną definicje obiektu. ... mirror.h #ifndef MIRROR_H#define MIRROR_Hclass Mirror { Mirror* wsk; bool is;public: Mirror(); Mirror(Mirror* src); bool test() const;};#endif plik5.cpp #include "mirror.h"#include <iostream>extern Mirror V4;Mirror V5(V4);Mirror::Mirror():wsk(0), is(true) {}Mirror::Mirror(Mirror* src): wsk(src), is(false) {}bool Mirror::test() const { if (wsk) return wsk->test(); else return is;}int main() { (V5.test()) ? std::cout << "true" : std::cout << "false"; return 0;} testowane na gcc 4.4.1: g++ plik5.cpp plik4.cpp plik3.cpp plik2.cpp plik1.cpp -o wynik1 g++ plik1.cpp plik4.cpp plik3.cpp plik2.cpp plik5.cpp -o wynik2 przynajmniej tak mi sie wydaje (; Edytowane 8 Sierpnia 2009 przez Drainer Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
danrok Opublikowano 9 Sierpnia 2009 Zgłoś Opublikowano 9 Sierpnia 2009 To coś zmieniło? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Drainer Opublikowano 9 Sierpnia 2009 Zgłoś Opublikowano 9 Sierpnia 2009 To coś zmieniło?jesli chodzi o wynik test() to nie (; Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Gość <account_deleted> Opublikowano 9 Sierpnia 2009 Zgłoś Opublikowano 9 Sierpnia 2009 Wydawało mi się, że zero to skalar i można przypisać do zmiennej, a NULL do wskaźnika, ale sprawdzałem później i okazuje się, że wsk = 0; też działa. Wydawało mi się, że się różni czymś. NULL to symbol - podobnie jak TRUE, FALSE - może reprezentować liczbę 0 - ale nie musi - dlatego też czasami jest inaczej traktowany przez kompilatory -> można się zdziwić ;) Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
danrok Opublikowano 11 Sierpnia 2009 Zgłoś Opublikowano 11 Sierpnia 2009 NULL to symbol - podobnie jak TRUE, FALSE - może reprezentować liczbę 0 - ale nie musi - dlatego też czasami jest inaczej traktowany przez kompilatory -> można się zdziwić ;) No właśnie tak mi się coś wydawało, że to 0 i NULL to nie zawsze jest to samo. Dzięki za wyjaśnienie ;) Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
Drainer Opublikowano 11 Sierpnia 2009 Zgłoś Opublikowano 11 Sierpnia 2009 to na koniec OT null vs 0: http://www.research.att.com/~bs/bs_faq2.html#null Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...