c++ wyjątki

SH
  • Rejestracja:prawie 13 lat
  • Ostatnio:około 6 lat
  • Postów:69
0

Hey,
Tak więc mam taki problem: Nie za bardzo rozumiem wyjątki...
Jak to działa ?

Kopiuj
 
klasa::klasa()
{
    try 
          {
            plik.open("............txt", ios::in | ios::out);
            if( plik.good() == true )
            {
                "Uzyskano dostep do pliku!" ;
            } else "Dostep do pliku zostal zabroniony!";
          }
          catch(OpenError)
          {
             
          }
    
}

chodzi mi o to, że chce napisac konstruktor który otwiera sobie plik ale jezeli go nie otworzy to chce by zwrócił wyjątek tam coś wykona i potem kolejna próba otwarcia itp itd
no i problem w tym, że nie rozumiem za bardzo jak to zrobić ponieważ:
nie ogarniam tutaj bloku try i kiedy stosuje throw
jest troche inaczej niż w pythonie bo.
No nie rozumiem mógł by mi ktoś wytłumaczyć ? Jak to działa i wgl ?
Bo czytałem o tym i dalej nie mam pojęcia jak zrobić to co sobie wymyśliłem. :(

2

klasy standardowej biblioteki dziedzicza z base_exception , poczytaj w referencji o wyjatkach
w klasie po ktorej dziedziczy fstream
http://cplusplus.com/reference/iostream/ios/exceptions/
i o jego budowie
http://cplusplus.com/reference/iostream/fstream/

gdzies chyba slyszalem ze nie powinno sie stosowac wyjatkow wewnatrz konstruktorow i destruktorow ale moze ktos lepiej sie znajacy odpowie ci dokladnie


peace
ChS

SH
Dzięki, w sumie to rozwiązałeś mój problem :)
KA
  • Rejestracja:prawie 13 lat
  • Ostatnio:około 12 lat
0

Co do używania mechanizmu wyjątków w konstruktorach i destruktorach to wydaje mi sie, ze chodzi o to, zeby wyjatek nie był rzucany poza konstruktor/destruktor tylko łapany wewnątrz i tam byłaby odpowiednia reakcja na dany błąd.

Endrju
  • Rejestracja:około 22 lata
  • Ostatnio:ponad rok
0

Wyrzucanie wyjątku z destruktora jest niebezpieczne i nie powinno się tego nigdy robić. Problem pojawia się, kiedy do wyrzucenia wyjątku z destruktora dojdzie podczas "odwijania stosu" po wyrzuceniu innego wyjątku. Który wyjątek miałby być wtedy obsłużony? Standard mówi, że w takim wypadku należy wywołać terminate(), które zasadniczo ubije nam program.

Z konstruktorami jest inaczej. Konstruktor może wyrzucić wyjątek i nic strasznego się nie stanie. Jednak destruktor nie zostanie wywołany. Oznacza to, że jeżeli alokowano jakieś zasoby przed wyrzuceniem wyjątku to nie zostaną one zwolnione. Na tę okazję wymyślono technikę RAII.


"(...) otherwise, the behavior is undefined".
OA
42 sekundy szybciej. ;-)
OA
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 10 lat
  • Postów:95
0

W konstruktorach można spokojnie używać wyjątków.
W destruktorach kategorycznie nie wolno, jako że mogą prowadzić do katastrofy przy próbie odwikłania stosu. Przykład:

Kopiuj
#include <iostream>
using namespace std;

class Test {
public:
    Test() {
        cout << "Test()" << endl;
    }

    void f() {
        cout << "f(), throwing 5..." << endl;
        throw 5;
    }

    ~Test() {
        cout << "~Test(), throwing 3..." << endl;
        throw 3;
    }
};

int main() {
    try {
        Test t;
        t.f();
    } catch (...)  {
        cout << "To sie nie wykona." << endl;
    }

    return 0;
}
0

Rzucanie wyjątków w konstruktorze też nie jest dobrym pomysłem, bo gdy konstruktor nie wykona się do końca to potem nie zostanie wywołany dla niego destruktor, wiec jest prawdopodobieństwo wystąpienia memory leaka.

Kopiuj
#include <iostream>
using namespace std;
 
class Test {
public:
    static int i ;
 
   Test() {
     objid = i++;
     cout << "Test() " << objid << endl;
     if(i == 3) throw 3;
    }
 ~Test() {
     cout << "~Test()" << objid << endl;
   }
 int objid;
};

int Test::i = 0;

int main() {
    try {
        Test t[5];
    } catch (int i)  {
        cout << "catch " << i << endl;
    }
 return 0;
}

Output:

Kopiuj
Test() 0
Test() 1
Test() 2
~Test()1
~Test()0
catch 3 

@up del sry

msm
@up del sry - done (ten up to był przypadkowo wysłany drugi post)
Endrju
Dowiedz się co to RAII.
0

myhm, no to dobrze uslyszalem, dalej jednak nie uzywam wyjatkow.
Do tej pory tworze klasy ktore maja okreslone stany na bool albo na maskach stanu, jak uwazacie lepsze jest takie rozwiazanie konstrukcji klas:
class klasa_bez_wyjatkow{
enum stan_{ 1, 2 };
bool stan[1];
bool funkcjaPlikowa(); // zakladam udana operacja stan[0]=true;
bool funkcjaModyfikujaca();//zakladam udana modyfikacje stan[1]=true;
void set_state(unsigned s_) stan[s_]=true;
void get_state() ...
void unset_state() ...
};

czy moze konstrukcja z wyjatkami

class klasa_z_wyjatkami{
void funkcjaPlikowa(); // zakladam ze wewnatrz zostanie wyrzucony blad operacji na pliku
void funkcjaModyfikujaca(); // zakldam ze gdy modyfikacja nie zostanie wykonana wyrzucony blad operacji
}
int main(){
klasa_bez_wyjatkow klasa_bez;
klasa_z_wyjatkami klasa_z;
klasa_bez.setState(klasa_bez.stan[klasa_bez.stan_.1]);
// po sprawdzeniu stanu po jednej iteracji w watku jadra programu wiem ze jest blad

//tutaj zaczyna sie watek iterujacy sprawdzanie stanu jadra
try{ klasa_z.funkcjaPlikowa() }
catch{ exception }
{
//po wychwyceniu wyjatku po kolejnej iteracji w watku jadra programu wiem ze jest blad
}
//tutaj konczy sie watek iterujacy sprawdzanie stanu jadra
}

no i tutaj biore pod uwage ze w programie jest jadro ktore wlasnie utrzymuje stan i dzieki temu steruje GUI (wyswietlam aktualnie porzadany stan) , oraz obiektami ktore odbieraja rezultaty z GUI ( oczywiscie obiekty maja wlasne stany i GUI ma tez wlasne stany ).

  1. Czy stosowanie tej techniki sprawdzania stanu aplikacji bez wyjatkow to dobre podejscie tworzenia architektury do programu?
  2. Czy uzywanie wyjatkow bez uzywania stanu to dobre podejscie? ( no dobra tego nie umiem nawet sobie wyobrazic )
  3. To w takim razie w jakich sytuacjach jest przydatne uzywanie wyjatkow.

peace
ChS

BZ
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 11 lat
0
00001010 napisał(a):
  1. Czy stosowanie tej techniki sprawdzania stanu aplikacji bez wyjatkow to dobre podejscie tworzenia architektury do programu?
  2. Czy uzywanie wyjatkow bez uzywania stanu to dobre podejscie? ( no dobra tego nie umiem nawet sobie wyobrazic )
  3. To w takim razie w jakich sytuacjach jest przydatne uzywanie wyjatkow.
  1. Nie
  2. Powinienes stosowac i to, i to (o ile jest taka potrzeba).
  3. Zawsze, po to, zeby nie doprowadzic do niezaplanowanego zakonczenia aplikacji, wyciekow pamieci itd.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)