metoda zwracająca obiekt klasy

0

cześć wszystkim mam taki oto kod prostej klasy


#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

class c_move
{
    private:
        double x;
        double y;
    public:
        c_move(double a = 0, double b = 0);
        c_move add (const c_move & m) const;
        void showmove() const;
};


c_move::c_move(double a, double b)
{
    x = a;
    y = b;
}


c_move c_move::add(const c_move & m) const
{
    double x_total = x + m.x;
    double y_total = y + m.y;
    
    c_move zmienna1(x_total, y_total);
    return zmienna1;
    
}


void c_move::showmove() const
{
    cout<< "x: " << x <<endl;
    cout<< "y: " << y <<endl;
}


 
    
int main()
{
    
    c_move zmienna1(5, 15);
    c_move zmienna2(10, 20);
    c_move zmienna3 = zmienna1.add(zmienna2);
    zmienna3.showmove();


    system("PAUSE");
}

czy możecie wytłumaczyć mi dlaczego wxdev++ nie wyrzuca błędu przy metodzie add? tworze w niej nowy obiekt klasy c_move inicjalizuje go wartościami obiektu wywołującego i przekazanego w parametrze i zwracam ten nowo utworzony obiekt jednak z tego co wyczytałem to taki obiekt jest usuwany z pamięci po opuszczeniu bloku i powinien wskazywać 'śmieci' dobrze mówię? bardzo proszę o krótkie wyjaśnienie pozdrawiam

0

Qt w takim miejscu zawsze wywala warning ze funkcja zwraca zmienna lokalna, ktora przestaje istniec po opuszczeniu funkcji, jednak jesli uzyjesz tej funkcji Od razu przy przypisaniu do jakiegos obiektu klasy to niewazne ze obiekt lokalny przestaje istniec, dane tego obiektu zostana przepisane. Mozna tak robic, tylko trzeba o tym pamietac.

0

Owszem jest niszczony:) ale dopiero po tym, jak zostanie przekopiowany w lini
c_move zmienna3 = zmienna1.add(zmienna2);
W ty mmiejscu wywołuje się niejawnie konstruktor kopiujący klasy c_move.

0

dzięki za odpowiedź, zgadza się w przypadku gdy zwracam referencje obiektu wyrzuca

[Warning] reference to local variable 'a' returned [enabled by default]

czyli zarówno w przypadku metod klasy jak i funkcji niezależnych mogę zwracać obiekty klas, zmienne, struktury utworzone wewnątrz bloku funkcji gdyż najpierw następuje zwrócenie zmiennej a dopiero później wartość ta jest usuwana z pamięci? pytam bo wyczytałem że zwracania jakichkolwiek zmiennych utworzonych lokalnie wewnątrz funkcji powinno się unikać własnie ze względu na niebezpieczeństwo utraty danych....

0

Referencja to odnośnik do zmiennej (taki inny wskaźnik). Skoro jest to zmienna lokalna to zostanie ona zniszczona i zwrócona referencja będzie błędna. Jeśli zwracasz przez wartość to zwracasz kopię zmiennej i wszystko jest cacy.

0

@emacs: gdyby nie można było zwracać zmiennych utworzonych lokalnie to praktycznie rzecz biorąc zwracanie czegokolwiek z funkcji mijałoby się z celem. Nie można zwracać referencji lub wskaźników do obiektów lokalnych. Tzn. można, ale trzeba się liczyć z konsekwencjami(np. wypowiedzenie od szefa :p).

0

rozumiem ale pomimo to, że zamieniłem definicje metody add tak żeby zwracała referencje do obiektu tworzonego lokalnie wewnątrz funkcji program dalej wyrzuca tylko warning a wartości zwrócone są właściwe.... rozumiem ze chcesz mi powiedzieć, że w przypadku zwracania referencji nigdy nie będę pewny czy zwróci prawidłowe wartości bo może wykonać się poprawnie a może wyrzucić śmieci lub przerwać program tak?

0

Zależy, jeżeli od razu wynik funkcji przypiszesz do zmiennej to nie będzie problemu, gorzej gdy zatrzymasz referencję, którą zwrócisz.

int& foo(int a, int b)
{
    int c = a + b;
    return c;
}

int main()
{
    int &a = foo(1, 2);
    int b = foo(10, 20);
    cout << a << " | " << b << endl;
}

To wcale nie wypisze liczb 3 i 30.

0

dokładnie chodziło mi o użycie referencji tak jak to zrobiłeś przy zmiennej b wtedy wszystko się zgadza wyrzuca tylko warning a zwrócenie referencji zmiennej lokalnej jest chyba wydajniejsze niż w przypadku zwracania kopi zmiennej? czyli w twoim przykładzie korzystanie z referencji tak jak to zrobiłeś ze zmienną b jest dopuszczalne? czy nie powinno się tego tak robić i koniec kropka?

0

Powiedzmy, że dopuszczalne, dopóki komuś nie wpadnie pomysł do głowy i nie zrobi tak jak w przypadku zmiennej a. To możesz być Ty, bo zapomnisz co się tam w tej funkcji dzieje, to może być ktoś inny używający Twojej funkcji.

Kod wypada pisać zawsze tak jakby ktoś inny mógł z niego korzystać, więc tak się nie powinno robić, niektórzy by za to kołem łamali.

0

Zależy, jeżeli od razu wynik funkcji przypiszesz do zmiennej to nie będzie problemu

Możesz podać źródło tych informacji?

Generalnie w takich przypadkach wcale nie jest pewne, że zostanie wykonana kopia. Większość kompilatorów wspiera coś, co nazywa się 'return value optimization' i pomaga właśnie w zwracaniu obiektów z funkcji.

0

Z tą dopuszczalnością to bym nie przesadzał. Standard języka C++ nie gwarantuje, że to zadziała.

0

Zwracać zmienną lokalną przez wartość jak najbardziej można.
Przez referencję nie powinno się, bo obiekt może zostać przedwcześnie zniszczony.

0

dziękuje wszystkim za odpowiedzi i wyjaśnienie tematu ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1