|
Informatyka UJ forum Rocznik 2005 - czyli najlepsze forum w sieci
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
kg86
zielony żul
Dołączył: 22 Gru 2005
Posty: 1194
Przeczytał: 0 tematów
Skąd: pochodze?
|
Wysłany: Sob 15:56, 27 Sty 2007 Temat postu: Pytania dotyczace programow na egzamin |
|
|
zaczalem analizowac programy i juz pojawilo sie cos, co wydalo mi sie istotne... mianowicie - jesli:
Kod: | struct wyjatekNumeryczny
{
void virtual raport()=0;
}; |
zamienie na:
Kod: | struct wyjatekNumeryczny
{
void virtual raport()
{
cout << "Zwykly wyjatek" << endl;
}
}; |
oraz usune & z catcha (//M1) to program w przypadku wystapienia ZlyDzielnik, nie wyrzuci: "Zly dzielnik", tylko: "Zwykly wyjatek"...
dlaczego klasa pochodne zostala skopiowana na klase macierzysta? czy to z czego innego wynika? :)
|
|
Powrót do góry |
|
|
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
kap00ch
Mistrz grilla
Dołączył: 09 Mar 2006
Posty: 1840
Przeczytał: 0 tematów
Skąd: ja sie tu wzialem?
|
Wysłany: Sob 16:18, 27 Sty 2007 Temat postu: |
|
|
gdybys sluchal wczoraj to bys wiedzial....bo akurat to omawialismy ;p i bylo pic tego browka? no bylo ?
bo wtedy wyolujesz raport na rzecz konkretnego obiektu )powstalego przez kopiowanie) co de facto wylacza nam polimorfizm...
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
kg86
zielony żul
Dołączył: 22 Gru 2005
Posty: 1194
Przeczytał: 0 tematów
Skąd: pochodze?
|
Wysłany: Sob 17:03, 27 Sty 2007 Temat postu: |
|
|
browarek nie mial tu nic do rzeczy :P po prostu nie pamietam wszystkich pytan i odpowiedzi, jakie padaly :P ale dzieki za wyjasnienie :)
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Fen
zielony żul
Dołączył: 22 Lut 2006
Posty: 946
Przeczytał: 0 tematów
Skąd: Bochnia
|
Wysłany: Sob 17:07, 27 Sty 2007 Temat postu: |
|
|
kg86 napisał: | browarek nie mial tu nic do rzeczy :P po prostu nie pamietam wszystkich pytan i odpowiedzi, jakie padaly :P ale dzieki za wyjasnienie :) |
dobra dobra... nie tłumacz się :D
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
oinopion
żul
Dołączył: 28 Lis 2005
Posty: 858
Przeczytał: 0 tematów
Skąd: Kraków
|
Wysłany: Sob 19:28, 27 Sty 2007 Temat postu: |
|
|
Kod: | #include <iostream>
using namespace std;
struct rok
{
int r;
rok() {}
rok(rok& x) {
cerr << "konstruktor kopiujacy\n" ;
}
} ;
int main()
{
rok a; a.r = 7;
rok b = rok(a); // inicjalizacja konstruktorem kopiujacym
}
|
Co powiecie o tym? Spróbujcie skompilować. U mnie trzeba dodać const do konstruktora [taki jest de facto standard u Stroustrupa, wbrew tego, co ma prof. Mrozek w wykładach].
Ale jednak:
Kod: | #include <iostream>
using namespace std;
struct rok
{
int r;
rok() {}
rok(rok& x) {
cerr << "konstruktor kopiujacy\n" ;
}
rok(const rok& x) {
cerr << "staly konstruktor kopiujacy\n" ;
}
} ;
int main()
{
rok a; a.r = 7;
rok b = rok(a); // inicjalizacja konstruktorem kopiujacym
} |
Ten kod wywali na cerr "konstruktor kopiujacy" [u mnie]. Czyli ten z const'em nie jest używany.
Trochę to wszystko zawiłe.
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
pazabo
pijak
Dołączył: 02 Lut 2006
Posty: 60
Przeczytał: 0 tematów
Skąd: Kraków
|
Wysłany: Sob 20:03, 27 Sty 2007 Temat postu: |
|
|
Co ciekawsze, inne użycie konstruktora kopiującego bez const działa:
Kod: | #include <iostream>
using namespace std;
struct rok
{
int r;
rok() {}
rok(rok& x) {
cerr << "konstruktor kopiujacy\n" ;
}
} ;
int main()
{
rok a; a.r = 7;
rok b(a); // inicjalizacja konstruktorem kopiujacym
} |
WFT?? A myślałem, że C++ rozumiem :]
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Pawel Str.
pijak
Dołączył: 06 Lut 2006
Posty: 429
Przeczytał: 0 tematów
Skąd: Ze starszego roku / Z Gorlic
|
Wysłany: Sob 20:03, 27 Sty 2007 Temat postu: |
|
|
@oinopion
Trafiliście na nieźle zakręcone kwestie w C++.
Wnioski z rozmowe ze Stefanem i czytania tego, co zwróciło google:
Cytat: |
A c = A();
means
"A()" creates an instance of A (as a temporary)
"A c =" is an invocation of the copy ctor.
|
Przy czym w takich wypadkach kompilator ma prawo pominąć (elide) wywołanie konstruktora kopiującego - dla optymalizacji (nawet jeśli występowały skutki uboczne!). Jednak nawet w sytuacji, gdy pomija to wywołanie, musi sprawdzić, czy wszystkie założenia, w tym dostępność (private/protected/public) są spełnione. W tej sytuacji właśnie coś takiego występuje - konstruktor kopiujący jest niezbędny (a wprowadzając rok(rok& r) zakazałeś budowy automatycznego konstruktora kopiującego), ale jest pomijany.
Weird.
Stefan napisał: |
a już człowiek myślał, że wszystko wie o konstruktorach! :P
|
-- Edit --
@pazabo
Stefan napisał: |
Stefan :: 18:46:19 / S 18:45:33
rok b = rok(a);
to copy initialization
Stefan :: 18:46:35 / S 18:45:49
i jest różne od direct initialization
rok b(a); // tu wszystko działa
|
Ostatnio zmieniony przez Pawel Str. dnia Sob 20:08, 27 Sty 2007, w całości zmieniany 1 raz
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Rogal
Zjeb z kaszanką
Dołączył: 13 Mar 2006
Posty: 1745
Przeczytał: 0 tematów
Skąd: koło podbiegunowe
|
Wysłany: Sob 20:07, 27 Sty 2007 Temat postu: |
|
|
mój g++ wymaga oczywiście wersji z constem, i wyświetla to co powinien, czyli "staly konstruktor kopiujacy"
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Pawel Str.
pijak
Dołączył: 06 Lut 2006
Posty: 429
Przeczytał: 0 tematów
Skąd: Ze starszego roku / Z Gorlic
|
Wysłany: Sob 20:08, 27 Sty 2007 Temat postu: |
|
|
@rogal - która wersja? <4.0?
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
pazabo
pijak
Dołączył: 02 Lut 2006
Posty: 60
Przeczytał: 0 tematów
Skąd: Kraków
|
Wysłany: Sob 20:17, 27 Sty 2007 Temat postu: |
|
|
to chyba o coś innego chodzi:
wywółuje najpierw konstruktor tworzący obiekt tymczasowy "rok(a)" a potem chce go skopiować konstruktorem kopiującym ale nie może. Dlatego wersje:
Kod: | rok b(a);
rok b = a; |
działają (bo nie tworzą obiektu tymczasowego). Chociaż to nie tłumaczy czemu z konstruktorem const miało by działać.
@Pawel Str.: u mnie na GCC 4.1.1 wszystko zachowuje się jak tomek napisał, więc to nie wersja kompilatora
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Pawel Str.
pijak
Dołączył: 06 Lut 2006
Posty: 429
Przeczytał: 0 tematów
Skąd: Ze starszego roku / Z Gorlic
|
Wysłany: Sob 20:21, 27 Sty 2007 Temat postu: |
|
|
@pazabo - ale idea podobna. Konstr. kopiujący jest wymagany przy obiekcie tymczasowym (obiekty tymczasowe *nigdy* nie mogą być przypisane do non-const referencji - nie ważne czy w konstuktorze czy w zwykłej metodzie), ale kompilator korzysta z przywileju pominięcia kopii i buduje obiekt od razu w odpowiednim miejscu. (więc de facto nie ma obiektu tymczasowego).
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Rogal
Zjeb z kaszanką
Dołączył: 13 Mar 2006
Posty: 1745
Przeczytał: 0 tematów
Skąd: koło podbiegunowe
|
Wysłany: Sob 20:23, 27 Sty 2007 Temat postu: |
|
|
Jak dla mnie to wszystko działa dokładnie tak jak powinno z tych powodów o których napisał pazabo.
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
pazabo
pijak
Dołączył: 02 Lut 2006
Posty: 60
Przeczytał: 0 tematów
Skąd: Kraków
|
Wysłany: Sob 20:29, 27 Sty 2007 Temat postu: |
|
|
mhm
Cytat: | obiekty tymczasowe *nigdy* nie mogą być przypisane do non-const referencji |
czy to znaczy, że jak referencja jest const to mogą być przypisane? Bo nie wiem czemu to nie działa:
Kod: | #include <iostream>
using namespace std;
class rok {
public:
int r;
rok() {}
rok(rok & rr) {}
};
void wypisz(const rok & rr) {
cerr << rr.r << endl;
}
int main() {
rok a;
a.r = 7;
wypisz(a);
wypisz(rok(a));
} |
bo tu jest konstruktor od obiektu (nietymczasowego) a, a potem obiekt tymczasowy przekazywany jest jako stała referencja. Co ciekawsze jak się doda const w konstruktorze kopiującym, to działa, czyli dalej nie rozumiem.. :?
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
pazabo
pijak
Dołączył: 02 Lut 2006
Posty: 60
Przeczytał: 0 tematów
Skąd: Kraków
|
Wysłany: Sob 20:33, 27 Sty 2007 Temat postu: |
|
|
@Pawel Str.: jakbyś mógł podać więcej szczegółów tego o czym pisałeś
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Pawel Str.
pijak
Dołączył: 06 Lut 2006
Posty: 429
Przeczytał: 0 tematów
Skąd: Ze starszego roku / Z Gorlic
|
Wysłany: Sob 20:37, 27 Sty 2007 Temat postu: |
|
|
Tak. Do referencji typu const mogą być przypisane.
Prosty test:
Kod: |
#include <iostream>
class A {
public
static A f() {
std::cout << "generator\n";
return A();
}
static void g(A& nonconstref) {
std::cout << "Nonconstref\n";
}
};
int main() {
A::g(A::f()); // nie działa
A a = A::f();
A::g(a); // działa.
}
|
A Twój kod nie działa z tych samych powodów, z jakich nie może być tam linii rok b = rok(a).
-- edit--
fora.pl coś nie najlepiej dzisiaj działają. IRC?
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Stefan
pijak
Dołączył: 22 Lis 2005
Posty: 173
Przeczytał: 0 tematów
|
Wysłany: Sob 21:02, 27 Sty 2007 Temat postu: |
|
|
Ależ to wszystko zakręcone... :) Mam nadzieję, że nic nie nakłamię :P
pazabo napisał: |
Kod: | #include <iostream>
using namespace std;
class rok {
public:
int r;
rok() {}
rok(rok & rr) {}
};
void wypisz(const rok & rr) {
cerr << rr.r << endl;
}
int main() {
rok a;
a.r = 7;
wypisz(a);
wypisz(rok(a));
} |
bo tu jest konstruktor od obiektu (nietymczasowego) a, a potem obiekt tymczasowy przekazywany jest jako stała referencja. Co ciekawsze jak się doda const w konstruktorze kopiującym, to działa, czyli dalej nie rozumiem.. :? |
Więcej. Po wywołaniu rok(a) dostajesz r-wartość. Implementacja ma dwa wybory:
- związać tą r-wartość bezpośrednio z referencją
- stworzyć obiekt tymczasowy poprzez konstruktor kopiujący.
Nieważne, którą taktykę wybierze (zazwyczaj tą pierwszą) - konstruktor do wykonania kopii z r-wartości do obiektu tymczasowego musi być dostępny. Ponieważ nie można wiązać r-wartości z niestałymi referencjami, konieczny jest konstruktor kopiujący pobierający argument const&.
Jeśli dostępny jest odpowiedni konstruktor, to obiekty tymczasowe można wiązać ze stałymi referencjami i zostaną one zniszczone dopiero wtedy, gdy skończy się zasięg referencji.
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
pazabo
pijak
Dołączył: 02 Lut 2006
Posty: 60
Przeczytał: 0 tematów
Skąd: Kraków
|
Wysłany: Sob 21:16, 27 Sty 2007 Temat postu: |
|
|
czyli kompilator robi jeszcze konstruktorem jakąś osobną referencję do zmiennej tymczasowej?
btw. kolega mi napisał, że na virgo to działa, więc coś tu nie gra :?
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Pawel Str.
pijak
Dołączył: 06 Lut 2006
Posty: 429
Przeczytał: 0 tematów
Skąd: Ze starszego roku / Z Gorlic
|
Wysłany: Sob 21:27, 27 Sty 2007 Temat postu: |
|
|
Na virgo jest stare gcc - 3.3 albo 3.4; im nowsza wersja tym zgodniejsza ze standardem (my przed egzaminem znaleźliśmy bardzo ciekawą kwestię widoczności nazw w szablonach - 3.4 działało zgodnie ze standardem, więc kod prof. Mrozka się nie kompilował, 3.3 zawierało błąd).
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Robson
zielony żul
Dołączył: 21 Paź 2005
Posty: 1274
Przeczytał: 0 tematów
Skąd: Z Lasu :]
|
Wysłany: Sob 21:34, 27 Sty 2007 Temat postu: |
|
|
Hehe trafiliscie dokładnie na to na co ja trafiłem przy projekcie z P2... jak przerabiałem starą klase z P1 na templaty. Klasa która zwracała obiekt tymczasowy który był takim małym centrum dowodzenia... No i wtedy działał... w VC++... tam byly pominiete consty... DevC++ od razu zaczał sie o nie pluc...
Sprawa jest naprawde paskudna...
Po prostu nie mozna przekazywać przez referencje obiektów tymczasowych, takie jest tłumaczenie. A wyglada na to ze A b = A(a); to to samo co A b(A(a)) no i tu jest obiekt chwilowy.... Dla mnie to tak wyglada... w sumie to chyba to juz zostało powiedziane.. ale nie chce mi sie uzywac backspace..;)
Najgorsze jest to ze kompilatory zachowuja sie naprawde "różniscie" w takich przypadkach :|
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Pawel Str.
pijak
Dołączył: 06 Lut 2006
Posty: 429
Przeczytał: 0 tematów
Skąd: Ze starszego roku / Z Gorlic
|
Wysłany: Sob 21:42, 27 Sty 2007 Temat postu: |
|
|
@Robson - my trafiliśmy na coś ciekawszego. Przy dziedziczeniu klas szablonowych nie można wprost odwoływać się do składników klasy bazowej - trzeba robić this->składnik, bo nazwy zależne od parametrów są wiązane w późniejszej fazie. Stare gcc te odwołania uważało za niezależne od szablonu i wiązało nazwy wcześnie, więc kod działał.
Wracając do głównego wątku.
Obiektów tymczasowych nie wolno przekazywać przez *niestałe* referencje. Przez stałe działają. Co ciekawsze na obiekcie tymczasowym wolno wywołać niestałą metodę składową.
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Stefan
pijak
Dołączył: 22 Lis 2005
Posty: 173
Przeczytał: 0 tematów
|
Wysłany: Sob 21:47, 27 Sty 2007 Temat postu: |
|
|
[link widoczny dla zalogowanych]
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
oinopion
żul
Dołączył: 28 Lis 2005
Posty: 858
Przeczytał: 0 tematów
Skąd: Kraków
|
Wysłany: Nie 0:04, 28 Sty 2007 Temat postu: |
|
|
Pawel Str. napisał: | @Robson - my trafiliśmy na coś ciekawszego. Przy dziedziczeniu klas szablonowych nie można wprost odwoływać się do składników klasy bazowej - trzeba robić this->składnik, bo nazwy zależne od parametrów są wiązane w późniejszej fazie. Stare gcc te odwołania uważało za niezależne od szablonu i wiązało nazwy wcześnie, więc kod działał. |
Taaaa..... chyba z 10 godzin nad tym spędziłem przy jednym z programików na P2... I potem poszedłem do dr Kozika i pytam go o to, pokazuje na virgo... i tam zonk bo wszystko działa.
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
nathaniel
pijak
Dołączył: 25 Paź 2005
Posty: 229
Przeczytał: 0 tematów
Skąd: Bielsko-Biała
|
Wysłany: Nie 0:51, 28 Sty 2007 Temat postu: |
|
|
Więc ja zadałem sobie pytanie, co zrobić żeby utworzyć PojemnikSortujacy<rok,3> i oto odpowiedź:
Kod: |
struct rok{
int r;
rok(){};
rok(int x):r(x){};
operator int(){return r;}; //funkcja konwertujaca rok na int
bool operator<(rok const& r2) const {return r<r2.r;}
};
//bool operator<(rok const& r1, rok const& r2) {return r1.r < r2.r;};
|
wtedy nie trzeba zmieniać typu zmiennych p,q i r. Załatwia to za nas funkcja konwertująca, o której istnieniu dopiero niedawno się dowiedziałem...
Może się komuś przyda :)
Ale teraz moje pytanie: jak stworzyć pojemnik sortujący od stringa? Czy da się stworzyć funkcje konwertujące globalne (w kontekście string <-> int)?
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Krisowski
pijak
Dołączył: 05 Mar 2006
Posty: 218
Przeczytał: 0 tematów
Skąd: z nikąd
|
Wysłany: Nie 13:15, 28 Sty 2007 Temat postu: |
|
|
Takie pytanie:
jak zmienimy
Kod: | struct argumentUjemny : wyjatekNumeryczny{
void raport(){
cout << "===> Ujemny argument " << endl;
}
}; |
na
Kod: | struct argumentUjemny : protected wyjatekNumeryczny{
void raport(){
cout << "===> Ujemny argument " << endl;
}
}; |
to program się wywali jak podamy liczbę ujemną. Podobnie jest jak damy private i/lub jak zrobimy to samo ze strukturą zlyDzielnik i podamy p < 2. Natomiast to nie ma wpływu na strukturę brakPodzielnosci (program działa dobrze). Czy w tym przypadku mechanizm wirtualności z jakiegoś powodu nie zadziała (obie te struktury są łapane przez referencję do wyjatekNumeryczny).
Jak zmienimy strukt na class w zlyDzielnik i argumentUjemny nastąpi podobny błąd. Czy to jest spowodowane tym samym??
|
|
Powrót do góry |
|
|
Zobacz poprzedni temat :: Zobacz następny temat |
Autor |
Wiadomość |
Rogal
Zjeb z kaszanką
Dołączył: 13 Mar 2006
Posty: 1745
Przeczytał: 0 tematów
Skąd: koło podbiegunowe
|
Wysłany: Nie 13:18, 28 Sty 2007 Temat postu: |
|
|
Z tego co mówił Bartek to jeśli dziedziczenie nie jest publiczne to tak jakby jest ono nie widoczne na zewnątrz... Tj. w tym przypadku argumentUjemny zachowuje się tak jakby nie był klasą pochodną po wyjątkuNumerycznym.
|
|
Powrót do góry |
|
|
|
|
Nie możesz pisać nowych tematów Nie możesz odpowiadać w tematach Nie możesz zmieniać swoich postów Nie możesz usuwać swoich postów Nie możesz głosować w ankietach
|
fora.pl - załóż własne forum dyskusyjne za darmo
Powered by phpBB © 2001, 2005 phpBB Group
|