2009-08-01 8 views
16

Może to być krótki & proste pytanie, ale nigdy nie znalazłem satysfakcjonującej odpowiedzi na to:C++ main() w dużej OOP projekt

Jaki kod jest główną funkcją() zazwyczaj składają się w sposób duży projekt C++? Czy błędnym założeniem byłoby myślenie, że zwykle jest to inicjowanie (zawijanie) obiektu klasy i wywoływanie w nim funkcji, aby wyłączyć te rzeczy?

Dlaczego metoda main() nie jest metodą w pierwszej kolejności? Czy ma zachować zgodność wsteczną z C?

+1

Powód, dla którego nie jest funkcją członka, polega na tym, że będziesz potrzebował sposobu na określenie klasy, której jest członkiem. C++ nie ma niczego takiego jak manifest Javy i nie ma refleksji. –

+0

z poziomu bardziej koncepcyjnego, każdy program potrzebuje punktu wejścia, w przypadku "klasycznego" C++ jest to plik wykonywalny, który kompilator tworzy, kiedy program się rozpoczyna nie istnieje klasa, która mogłaby być metodą. W językach interpretowanych środowisko wykonawcze wykonuje się najpierw i ustawia kontekst, w którym aplikacja ma się uruchamiać przed jej uruchomieniem, więc punkt wejścia będący metodą/członkiem jakiejś uprzednio ustawionej klasy jest możliwy, jeśli język/środowisko wykonawcze pozwoli/zapragnie. – Mark

+2

@ Mark: co? Kompilator jest odpowiedzialny za wysyłanie kodu w celu inicjowania różnych rzeczy, w tym statycznych członków klas, przed uruchomieniem funkcji main(). Do tego stopnia, że ​​klasy mogą istnieć w środowisku wykonawczym w C++, istnieje wiele klas istniejących przed wywołaniem punktu wejścia. Może nawet istnieć wiele obiektów. –

Odpowiedz

10

W moim kodzie jest to w zasadzie wywołanie konstruktora, prawdopodobnie wywołanie metody i obsługa wyjątków. Jest to główny za rękę z moich projektów (nagłówki i komentarze pominięty, a formatowanie pomieszane przez SO, jak zwykle):

int main(int argc, char * argv[]) { 
    int result = 0; 
    try { 
     CLIHandler ch(argc, argv); 
     result = ch.ExecCommand(); 
    } 
    catch(const Exception & ex) { 
     result = ExceptionHandler::HandleMyError(ex); 
    } 
    catch(const std::exception & ex) { 
     result = ExceptionHandler::HandleOtherError(ex); 
    } 
    catch(...) { 
     result = ExceptionHandler::HandleUnknownError(); 
    } 
    return result; 
} 
+0

Dlaczego po prostu nie zastąpić całego 'result =' z 'return'? – GManNickG

+2

Umyć usta! Czy nigdy nie słyszałeś o wymogu, że we wszystkich dobrze ustrukturyzowanych kodach funkcja musi mieć tylko jeden punkt wyjścia ???? Ale mówiąc poważnie, moja metoda jest łatwiejsza do debugowania, ponieważ masz zmienną do sprawdzenia. –

+0

Ah, widzę lol. Przestraszyłeś mnie. Byłem jak "FUUU- co ?!". Chyba nigdy nie musiałem sprawdzać zmiennej zwracanej, moja procedura obsługi błędów wypisuje ją razem z wyjątkiem. W przeciwnym razie nasz kod jest taki sam. – GManNickG

1

Krótka odpowiedź: to zależy. Może również utworzyć kilka lokalnych obiektów, które są potrzebne na czas trwania programu, skonfigurować je, opowiedzieć o sobie nawzajem i wywołać długo działającą metodę na jednym z nich.

Program wymaga punktu wejścia. Jeśli main musi być metodą na obiekcie, jaki powinien być typ klasy?

Jako globalny punkt wejścia może wybrać, co należy skonfigurować.

2

Kopalnia zwykle zrobić

  • wiersza polecenia parsowania
  • inicjalizacji najwyższego poziomu obiektów
  • obsługa wyjątków
  • wejściem głównym 'exec' pętlę

Jak rozumiem , int main(int argc, char *argv[]) jest zasadniczo konwencją ze względu na dziedzictwo C. Nigdy nie wydawało mi się to dziwne, ale raczej użyteczne. C++ w końcu rozszerza C ... (i tak, jest tu duża różnica, ale to nie było tutaj pytanie).

2

Tak, powodem jest kompatybilność wsteczna. main jest jedynym punktem wejścia dozwolonym w programie C, który produkuje pliki wykonywalne, a zatem w programie C++.

Co do tego, co zrobić w C++, to zależy. W ogóle, kiedyś:

  • przeprowadzić globalną inicjalizacji (np podsystemu rejestrowania)
  • argumentów wiersza poleceń parse i określić właściwą klasę zawierających je
  • przeznaczyć obiekt aplikacji, ustawienie go itd.
  • uruchom obiekt aplikacji (w moim przypadku metoda nieskończonej pętli, programowanie GUI)
  • do finalizacji po ukończeniu zadania przez obiekt.

no i zapomniałem najważniejszą część aplikacji

  • pokazać ekran powitalny
0

Można użyć statycznej funkcji składowej klasy zamiast główny z MSVC++ kompilator, wybierając punkt wejścia w ustawieniach projektu, pod zaawansowanymi opcjami linkera.

To naprawdę zależy od twojego projektu, od tego, co chcesz tam umieścić ... jeśli jest mały, możesz umieścić w nim pętle wiadomości, inicjalizację i kod zamknięcia. W większych projektach będziesz musiał przenieść je do swoich własnych klas/funkcji lub mniej mieć monolityczną funkcję punktu wejścia.

0

Nie wszystkie aplikacje C++ są OOP i tak czy inaczej, cały kod wymaga od punktu wejścia pewnego punktu wejścia.

Kiedy piszę kod OOP, mój main() ma tendencję do włączania instancji obiektu, może być kontynuowany przez niektóre dane wejściowe użytkownika. Robię to w ten sposób, ponieważ czuję, że "dzieło" ma być wykonane wewnątrz obiektu, w przeciwnym razie kod nie jest napisany w "duchu" OOP.

0

Realnie duże projekty zwykle nie obejmują tylko jednego programu. Stąd będzie kilka plików wykonywalnych, każdy z własną główną. Często zdarza się, że te pliki wykonywalne komunikują się asynchronicznie za pośrednictwem kolejek.

Tak, każda główna ma tendencję do bycia bardzo małymi, inicjowania ramek lub cokolwiek innego.

Masz na myśli, dlaczego funkcja main() jest funkcją, a nie klasą? Jaka klasa byłaby to metoda? Myślę, że to głównie dziedzictwo C++ z C, ale ... wszystko zaczęło się gdzieś :-)

+1

główny to funkcja, a nie metoda ... – micmoo

+0

Dzięki, tak, masz rację. – djna

0

Zwykle używam głównym do czytania w linii poleceń, inicjalizacji zmiennych globalnych, a następnie wywoływanie odpowiednich funkcji/metod.

1

Moja funkcja main() często konstruuje różne obiekty najwyższego poziomu, nadając im odniesienia do siebie. Pomaga to zminimalizować sprzężenie, zachowując dokładne relacje między różnymi obiektami najwyższego poziomu ograniczonymi do głównego.

Często te obiekty najwyższego poziomu mają różne cykle życiowe, z metodami init(), stop() i start(). Funkcja main() zarządza wprowadzaniem obiektów w pożądany stan roboczy, czeka na wszystko, co wskazuje na czas zamknięcia, a następnie zamyka wszystko w kontrolowany sposób. Ponownie pomaga to w utrzymaniu właściwego rozłączenia i utrzymuje zarządzanie cyklem życia na najwyższym poziomie w jednym, łatwo zrozumiałym miejscu. Widzę ten wzorzec bardzo często w systemach reaktywnych, szczególnie tych z wieloma wątkami.