Zwracanie jednego i wielu obiektów z funkcji

0

Witam,
dostałem takie zadanie, w którym mam m. in. stworzyć funkcję przyjmującą jako argumenty tablicę obiektów i wyszukiwaną wartość. Funkcja powinna zwracać do miejsca wywołania obiekt lub obiekty. Gdy obiekt jest jeden, to wiem, jak to zrobić, ale proszę o podpowiedź, jak zwrócić wiele obiektów?

4

zwróć tablicę tych obiektów. Daj jeszcze próbkę kodu lub polecenie, bo nie za bardzo wiadomo o co chodzi ze zwracaniem wielu obiektów.

0

Środowisko to Visual Studio 2019, a język C++.
Funkcja szukająca:

Klasa znajdz(Klasa tabc[], int wyszukane) {
	for (int i = 0; i <= 8; i++)
	{
		if (tabc[i].wartosc == wyszukane)
		{
			return tabc[i];
		}
	}
}
0

Pytając o środowisko bardziej myślałem o jakiejś bibliotece np GUI, posiadającej hierarchię klas od jakiegoś "korzenia" XxxxObject (tak mają Qt albo MFC - co nie oznacza pochwały MFC). Wtedy jest możliwość zrobienia eleganckiego API, bo i tablica (oczywiście ta z frameworka), lista i pojedynczy obiekt jakiejś klasy dziedziczą z głównego XxxxxObjectu (jak jest natywnie w Javie i C#).

Ponieważ C++ nie ma samo w sobie koncepcji takiej klasy "korzenia", zostaje zwracanie kontenera, być może z jednym elementem.
Zamiast zwykłej tablicy, która zmusza do podania licznika, znacznie lepiej jest zwracać jakiś std::vector, std::list czy co sobie wybierzesz.

BTW w tym co zamieszczasz, użycie tablicy[] i szukanie do ósemki jest chore, też użyj kontenera.

1

Sygnatura funkcji może wyglądać np tak:

std::vector<Klasa> znajdz(const std::vector<Klasa>& tabc, int wyszukane);

W funkcji zbierasz wszystkie obiekty z tabc spełniające warunek do lokalnego wektora i go na koniec zwracasz.

0

Ok, a jeszcze, jak mogę po zwróceniu wektora wyświetlić zawartość obiektów w nim zawartych(wywołać metodę "przedstaw się" na każdym)? Mam pętle for, tylko nie wiem, jak odwołać się do zwróconego wektora, czy muszę go zapisać do nowego w funkcji main?

0

W funkcji znajdz zwracam wektor, a w main mam taką pętlę:

for (int i = 0; i <= znajdz(tabc,wartosc).size(); i++) {.   (1)
		znajdz(tabc, wartosc)[i].przedstaw_sie;
		}

W wektorze zapisane są wyniki wyszukiwania( obiekty typu Klasa). Nie wiem, jak te obiekty wyświetlić. Kompilator zwraca mi błędy :
po lewej .size() musi być struct/union.
wyrażenie(1) musi mieć typ klasy, (znajdz jest podkreślone)

A funkcja znajdz tak wyglada teraz:

std::vector<Klasa> znajdz(const std::vector<Klasa>& tabc, int wyszukane){
	vector <Klasa> zwracany;
	for (int i = 0; i <= 11; i++)
	{
		if (tabc[i].wartosc1 == wyszukane)
		{
			zwracany.push_back(tabc[i]);
		}
	}
	return zwracany;

}
1

Sugerował bym użycie iteratora

for(std::vector<Klasa>::iterator it = v.begin(); it != v.end(); ++it) {
    it->przedstaw_się()
}


EDIT za podaną niżej pętlą foreach (bo taka de facto jest)  podpisuję się oboma ręcyma

BTW "klasyczny" środkowy warunek pętli u ciebie jest
a) ciężki (kosztowny)
b) błedogenny jeśli założymy, że dane jakoś żyją.
Generalnie mało satysfakcjonująca jest ta pętla.

0

Nie używaj magicznych liczb ( i <= 11 ). Gdyby wektor miał tylko trzy elementy, to miałbyś UB (Undefined Behavior).
Można to zrobić w taki sposób ( C++17 ):

using namespace std;

class Foo
{
public:
    int value {0};
    void introduce() const { cout << "My value is : "+to_string(value) << "\n"; }
};

vector<Foo> find( const vector<Foo>& data , int value )
{
     vector<Foo> result;
     for( const auto& element : data ) if( element.value == value ) result.push_back(element);
     return result;
}

int main() 
{
     for( const auto& element : find( {{2},{6},{5},{15},{5},{4}} , 5 ) ) element.introduce();
}

Ale pomyśl jednak o scaleniu funkcji wyszukującej find z wywołaniem metody klasowej introduce , tak aby zaoszczędzić sobie tworzenia niepotrzebnych bytów:

void find_and_introduce( const vector<Foo>& data , int value )
{
     for( const auto& element : data ) {  if( element.value == value )  element.introduce();  }
}

int main() 
{
     find_and_introduce( {{2},{6},{5},{15},{5},{4}} , 5 ) ;
}
0

Może byłby ktoś chętny odpłatnie(na privie) przejrzeć to co napisałem, poprawić?

0

Próbuje znaleźć błąd w tej funkcji, ale nie mogę. Przy konwertowaniu tablicy na vector, gdy próbuję wyświetlić zawartość wektora, to pokazuje 0. A wcześniej przy tablicy normalnie pokazuje. Czyli coś mam źle z konwersją tablicy?

	vector<Klasa> znajdz( Klasa przekazana[], int wyszukane) {
		vector <Klasa> zwracany;
		std::vector<Klasa> konwert(przekazana, przekazana + sizeof przekazana / sizeof przekazana[0]);
		cout << konwert.size();
		for (int i = 0; i < konwert.size(); i++)
		{
			if (konwert[i].wartosc1 == wyszukane)
			{
				zwracany.push_back(konwert[i]);
			}
		}
		return zwracany;
	}
2
Koner0 napisał(a):

Próbuje znaleźć błąd w tej funkcji, ale nie mogę. Przy konwertowaniu tablicy na vector, gdy próbuję wyświetlić zawartość wektora, to pokazuje 0. A wcześniej przy tablicy normalnie pokazuje. Czyli coś mam źle z konwersją tablicy?

vector<Klasa> znajdz( Klasa przekazana[], int wyszukane) {
...
std::vector<Klasa> konwert(przekazana, przekazana + sizeof przekazana / sizeof przekazana[0]);

Dlaczego nie korzystasz ze wskazówek, np gotowego nagłówka funkcji od @stryku . Każdy kiedyś był początkujący, ale potrzebujesz rozsądku, a nie strzelania na oślep (pewnie jakimiś kawałkami z googla)

Wyrażenie z sizeof jest błędne, sizeof(przekazana) jest 4 lub 8 (rozmiar wskaźnika, taka uroda C). Twój nagłówek funkcji z tablicą jest zupełnie nieużyteczny (brak wiedzy o rozmiarze tablicy)

Rzuć w cholerę myślenie w stylu C ( tu jest C++) - a zwłaszcza błędne

0

Próbowałem, jestem naprawdę początkujący :) Muszę ten program oddać dziś do północy, mocno zmęczony po prostu już jestem do tego. Powiedzielibyście, jak mogę tę tablicę przekonwertować na wektor obiektów?

0

Czyli nie da się tego przekonwertować ? Wcześniej, gdy miałem tę funkcję konwertującą w main to działało, ale spojrzałem na warunki zadania i musiałem tablice do funkcji przesłać, więc zmieniłem i teraz próbuję zmienić tę tablicę na wektor, żeby później go przeszukać. Da się ten kod jakoś poprawić ? :)

0

Uff, dzięki, uratowaliście mnie. Program działa, dzięki wszystkim za pomoc. :)

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