Skocz do zawartości
shoq

Zmiana Kolejności łączenia Plików W Linkerze (c++) Vs2008 Lub G++

Rekomendowane odpowiedzi

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 przez luqash

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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ś.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

... 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 przez Drainer

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Gość <account_deleted>

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

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...