• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

programowanie obiektowe+dobre praktyki

VPS Starter Arubacloud
0 głosów
367 wizyt
pytanie zadane 10 marca 2020 w C i C++ przez edwardkraweznik Dyskutant (9,930 p.)

Witam.

piszę sobie jakiś programik i potrzebuje aby funkcja zwracała 2 wartości, lub więcej (wydaje mi się, że returnem tego nie da rady zrobić) więc zrobienie czegoś takiego jest zgodne z dobrymi praktykami:

stworzyć klasę a w niej 2 zmienne.

stworzyć metodę w tej klasie, która wykonuje jakieś operacje i zapisuje to do tych zmiennych.

następnie przykładowo w mainie

uruchomić funkcje z jakimiś argumentami i z tego maina mieć dostęp do tych zmiennych.

PS: Kodu nie mam,zanim go napiszę chciałbym się upewnić, że takie rozwiązanie jest ok albo nieOK

w mainie wyglądało by to tak:

Klasa zmienna;
zmienna.funkcja(arg1, arg2);
cośtam << zmienna.zmienna1;
cośtam << zmienna.zmienna2;

 

komentarz 10 marca 2020 przez tkz Nałogowiec (42,000 p.)
Zależy też w jakim formacie zwracasz te dane, skoro zwracasz imie i nazwsiko, to może być vector par, vector struktur. Ogólnie, to zależy co chcesz zrobić.
komentarz 10 marca 2020 przez tkz Nałogowiec (42,000 p.)
Zmień edytor. VS Code ma to w standardzie.
komentarz 10 marca 2020 przez edwardkraweznik Dyskutant (9,930 p.)
a to tylko pod windowsem działa ?
komentarz 10 marca 2020 przez tkz Nałogowiec (42,000 p.)
Jest wersja na linuxy.
komentarz 10 marca 2020 przez edwardkraweznik Dyskutant (9,930 p.)
zajefajne :) przeformatowało mi wszytko :)

dzięki

2 odpowiedzi

0 głosów
odpowiedź 11 marca 2020 przez mokrowski Mędrzec (155,460 p.)
wybrane 11 marca 2020 przez edwardkraweznik
 
Najlepsza

Toje pytanie nie koniecznie dotyczy programowania obiektowego jako takiego. Można je raczej zawęzić do samej funkcji i zwracania z niej argumentów.

Jeśli zwrócisz parę (std::pair<..., ...>), to ograniczysz się wyłącznie do 2 elementów. Możesz co prawda każdy z nich powielić (czyli mieć parę w parze która to osadzona para ma ... parę...), ale to jest droga do przepaści problemów zrozumienia intencji zawartych w kodzie.

Para ma tę pozytywną właściwość, że jest naturalna dla 2 wartości nazywanych first i second. Problem jednak w tym że nazwy te nie przenoszą kontekstu i intencji stosowania. Jeszcze raz, to nie jest złe, tylko ma swoje konsekwencje (właśnie braku kontekstu stosowania i ogólnych nazw first i second które nie wiadomo co dokładnie w kontekście znaczą).

Jeśli zwrócisz strukturę (czyli w tym przypadku obiekt VO - value object), to masz "pojemnik na dane". Każdy z atrybutów może coś znaczyć i może ich być wiele. Dodatkowo możesz mieć kontrolę nad poprawnością kreacji bo w C++ struktura może posiadać konstruktor lub metody walidujące które mogą nie dopuścić do tworzenia danych niepoprawnych. 

Co do std::tuple<....>, do uwagi co do jasności intencji, są podobne jak dla std::pair<..., ...>. Tu masz jednak dostęp do danych przez std::get<X>(moja_tupla), gdzie X będzie miał wartości 0 do N co... znów nie mówi o co chodzi (pole pierwsze, pole drugie itd.). Krotka (jedna z nazw std::tuple<...>), przydaje się przy intensywnym stosowaniu szablonów oraz metaprogramowania i IMHO, nie powinna być wybierana jako domyślne rozwiązanie. Tym bardziej że std::get<X>(...), posiada argument w postaci szablonu i iterowanie po polach, wypcha Cię bezpośrednio w techniki szablonowe. Czasem tego chcesz, ale częściej bywa że nie :)

Możesz także wybrać (ale z całą pewnością nie jako domyślne rozwiązanie), zwrócenie wartości przez argument w funkcji. Jeśli będzie on referencją lub wskaźnikiem, nie będzie konieczności zwrócenia przez return. Tu jednak powinieneś mieć ważkie powody. Np. "ciężki obiekt" (co do objętości w pamięci lub kosztu kreacji), konieczność zwrócenia poprzez return z funkcji statusu (np. argumentu typu bool) lub inne. Funkcja wtedy będzie "wypełniała przesłany przez argument pojemnik na dane". Nie wybieraj jednak tego rozwiązania "bo tak", bo to nie jest dla osoby nieprzygotowanej intuicyjne. Czytelnik (i także Ty po kilku dniach), spodziewa się w pierwszej kolejności tradycyjnego działania funkcji ("wpada przez argument, zwraca przez return").

Jeszcze innym rozwiązaniem jest zwrócenie std::optional<...>. To wybierasz jednak np. wtedy, gdy zachodzi konieczność sygnalizowania że dane są dostępne lub ich brak. Dlaczego brak? Np. nie można ich uzyskać, przy tych argumentach w funkcji nie można ich policzyć itp. Takie podejście "wszystko albo nic".

Z funkcji można zwrócić także std::variant<...>. Najprościej (choć nie w sposób pełny), wytłumaczyć można ten typ danych jako unię. Jednak unię z mechanizmem wnioskowania jaki typ danych jest wewnątrz dostępny.

Jak dodasz do tego klasy to... jeszcze innym sposobem jest zwrócenie danych w postaci struktury/klasy, która definiowana jest wewnątrz funkcji i dziedziczy z argumentu zwracanego. Tu znów powinny być ważkie powody. Godzisz się na polimorfizm dynamiczny.

Hmm... może do tego ostatniego sposobu przykład. Jeśli inne sposoby nie są zrozumiałe, napisz.

#include <iostream>
#include <memory>

struct X {
    virtual void foo() const {
        std::cout << "X foo()\n";
    }
};

std::unique_ptr<X> make(int i) {
    struct Y: X {
        void foo() const override {
            std::cout << "Y foo()\n";
        }
    };
    struct Z: X {
        void foo() const override {
            std::cout << "Z foo()\n";
        }
    };
    if (i % 2) {
        return std::make_unique<Y>();
    }
    return std::make_unique<Z>();
}

int main() {
    auto x = make(2);
    // Usuń poniżej komentarz i sprawdź jak działa
    //auto x = make(1);
    x->foo();
}

Jak widać możliwości chyba wystarczająco wiele :)

komentarz 11 marca 2020 przez edwardkraweznik Dyskutant (9,930 p.)
nic nie kumam... ogarnołem sobie pairy działa to jak trzeba

tx za pomoc :)
komentarz 11 marca 2020 przez mokrowski Mędrzec (155,460 p.)
No to zrób sobie zakładkę i wróć po jakimś czasie. Przy wzroście doświadczenia, zrozumiesz :) Jeśli jednak nie rozumiesz dziś, to zapytaj a podam przykład/wytłumaczę :)
komentarz 11 marca 2020 przez edwardkraweznik Dyskutant (9,930 p.)
ok tx
0 głosów
odpowiedź 10 marca 2020 przez Michałełe Nałogowiec (25,600 p.)

PS: Kodu nie mam,zanim go napiszę chciałbym się upewnić, że takie rozwiązanie jest ok albo nieOK

Te rozwiązanie jest OK bo będzie działać tak jak chciałeś - można zwrócić 2 wartości z funkcji, ale trzeba użyć jakiś klas z STL ( de facto robimy to co napisałeś, stworzymy jakiś obiekt i do niego wsadzimy te zmienne) bądź też po prostu zwrócić je jako tablicę dwuelementową. Także jak na razie spróbuj swoim sposobem, a później możesz poczytać  o min. vector'ach czy pair'ach.

komentarz 10 marca 2020 przez edwardkraweznik Dyskutant (9,930 p.)
nie znam tych pairów czy jako to się zwie, ale

potrzebuję przy wywołaniu funkcji zmienne int, string i float

tego na vector się chyba nie zrobi, a na tych pairach ?

Podobne pytania

+1 głos
1 odpowiedź 342 wizyt
pytanie zadane 1 kwietnia 2021 w PHP przez michal_php Stary wyjadacz (13,700 p.)
+1 głos
2 odpowiedzi 342 wizyt
pytanie zadane 11 marca 2021 w SQL, bazy danych przez CSSoup Mądrala (6,460 p.)
+1 głos
2 odpowiedzi 481 wizyt
pytanie zadane 3 stycznia 2021 w JavaScript przez Bartx Bywalec (2,120 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...