2009-10-05 8 views
5

[EDIT 1 - dodał składnia trzeci wskaźnik (Dzięki Alex)]C++ DAL - Powrót referencyjny lub wypełnić Przekazywana w odniesieniu

Która metoda wolisz dla DAL i dlaczego z:

Car& DAL::loadCar(int id) {} 
bool DAL::loadCar(int id, Car& car) {} 
Car* DAL::loadCar(int id) {} 

Jeśli nie uda się znaleźć samochodu, pierwsza metoda zwróci wartość null, druga metoda zwróci wartość false.

Druga metoda spowoduje utworzenie obiektu Car na stercie i wypełnienie danymi wyszukanymi z bazy danych. Przypuszczalnie (mój C++ jest bardzo zardzewiały) oznaczałoby to kod wzdłuż linii:

Car& DAL::loadCar(int id) 
{ 
    Car *carPtr = new Car(); 
    Car &car= *carPtr; 
    car.setModel(/* value from database */); 
    car.setEngineSize(/* value from database */); 
    // etc 
    return car; 
} 

Thanks

Odpowiedz

5

Drugi jest zdecydowanie korzystne. Zwracasz odwołanie do obiektu, który został nowy. Dla użytkownika końcowego korzystającego z oprogramowania nie jest oczywiste, że zwracany obiekt wymagałby usunięcia. PLUS jeśli użytkownik robi coś takiego, to wskaźnik zgubiłby się.

Druga metoda polega zatem na sterowaniu pamięcią osoby dzwoniącej i powstrzymuje wszelkie dziwne błędy.

Edycja: Powrót przez referencję jest sensowny, ale tylko wtedy, gdy klasa rodzica, tj. DAL, kontroluje długość okresu odniesienia. tzn. jeśli klasa DAL zawiera wektor obiektów Car, wtedy zwrot referencji byłby sensowną rzeczą do zrobienia.

Edycja2: Nadal wolałbym drugi zestaw. Trzecia jest znacznie lepsza niż pierwsza, ale kończy się na tym, że wywołujący zakłada, że ​​obiekt jest inicjowany.

Można również

Car DAL::loadCar(int id); 

i nadzieją przyjąć kopię stosu.

Pamiętaj również, że możesz utworzyć rodzaj obiektu samochodu o wartości NULL, dzięki czemu zwrócisz obiekt będący "poprawnym" hash, ale nie zwróci on żadnych użytecznych informacji we wszystkich polach (i dlatego jest oczywiście inicjalizowany do danych śmieciowych)). To jest wzór obiektu zerowego.

+0

Dzięki. Nawet jeśli osoba dzwoniąca napisała "Car & myCar = dal.loadCar (id)", czy wskaźnik nie zostałby utracony? Czy istnieje mimo to kod non-DAL, aby usunąć pamięć utworzoną przez DAL? – ng5000

+0

Nie, jeśli osoba dzwoniąca napisała to, co napisałeś, pamięć "może" być wolna. Musisz zadzwonić "usuń &myCar;", aby to zrobić .. co wygląda bardzo dziwnie. – Goz

+0

Kopiowanie stosu może się nawet nie zdarzyć: w zależności od kompilatora i optymalizacji, (N) RVO może się uruchomić i wykonać operację równoważną # 1. W każdym razie, wyrzucenie wyjątku, gdy samochód nie zostanie znaleziony, będzie konieczne. –

4

Ponieważ tak czy inaczej przydzielasz obiekty na stercie, dlaczego nie rozważyć Car * LoadCar(), która zwraca NULL, jeśli wystąpi problem. W ten sposób nie ma żadnych ograniczeń z typami referencyjnymi (każda referencja musi być zainicjalizowana), a także mają środki do sygnalizowania przypadku błędu.

+0

Brzmi rozsądnie, zaktualizowano pytanie, aby dodać trzecią opcję. – ng5000

+0

Car & DAL :: loadCar (int id) nie może zwrócić NULL; nie ma zerowego odniesienia, tylko wskaźniki zerowe. – Massa