Prosta lista - operacje na elementach

Prosta lista - operacje na elementach
KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
0

Witam, napotkałem na pierwszy 'zgrzyt' w czasie nauki c++. Otóż w jednym zadaniu z książki jest takie info:

Co do odwiedzania kolejnych elementów listy i wykonywania operacji na tych elementach, to zwykle implementuje się to w postaci metody przyjmującej wskaźnik funkcji realizującej operację na elemencie:

Kopiuj
void visit(void (*pf)(Item &))

Tutaj pf wskazuje funkcję (nie metodę), przyjmującą argument w postaci referencji do Item, gdzie Item jest typem elementów listy. Metoda visit wywoła tę funkcję dla każdego elementu listy//.

Nie do końca rozumiem jak to interpretować.
Metoda odpowiada za kolejne przechodzenie przez elementy listy i wywoływanie na nich funkcji zewnętrznej?
Jeśli tak to dlaczego nie zrobić po prostu odpowiedniej metody do tych zmian, co daje ta funkcja zewnętrzna? Jedyne podejrzenie jakie mi się nasuwa to takie, że nie mamy dostępu do kodu klasy ale możemy napisać funkcję, która coś tam zrobi z tymi elementami, ale mogę gadać głupoty :p

Byłbym wdzięczny za wyjaśnienie albo jakiś mały przykład:)

spartanPAGE
  • Rejestracja: dni
  • Ostatnio: dni
1

Przykład:

Kopiuj
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

template<typename T>
struct list {
	vector<T> data;
	
	template<typename F>
	list<T> filter(F f) const {
		vector<T> result;
		copy_if(begin(data), end(data), back_inserter(result), f);
		return { result };
	}
	
	template<typename F>
	list<T> map(F f) const {
		vector<T> result(data.size());
		transform(begin(data), end(data), begin(result), f);
		return { result };
	}
	
	template<typename F>
	void each(F f) const {
		for_each(begin(data), end(data), f);
	}
};

int main() {
	(list<int>{{ 1, 2, 3, 4, 5, 6, 2016 }})
		.filter([](auto x){ return x % 2; })
		.map([](auto x){ return x*x; })
		.each([](auto x){ cout << x << " "; });
	return 0;
}

http://ideone.com/h67myx
output: 1 9 25

KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
0

Może inaczej :D

Zamieszczam swój kod (rozwiązanie zadania) wraz z próbą implementacji tej funkcji.

Kopiuj
// .h

#ifndef STK_H_
#define STK_H_

#include <iostream>

struct Str
	{
		char fullname[40];
		double payment;
	};
				
		void funkcja(Str & stru);

class Stack
{
	
	private:
		
		enum{MAX = 10};	
		Str stru[MAX];
		
		int top; //index szczytowego elementu
			
		
	public:
		
		Stack();
		bool is_full() const;
		bool is_empty() const;
		bool push(const Str & str);
		bool pop(Str & str);
		void show_list() const;
		void sort_list();
		void visit(void (*pf)(Str & str));
};

#endif 
Kopiuj
//  .cpp
	
	
#include <cstring>
#include "stk.h"	


void funkcja(Str & stru)
{
	std::cout<<"Payment"<<std::endl;
	int payment;
	std::cin>>payment;
	std::cin.get();
	std::cout<<"Podaj nowa nazwe...  ";
	char help[40];
	std::cin.getline(help,40);
	
	strcpy(stru.fullname,help);
	stru.payment = payment;
	
}

void Stack::visit(void (*pf)(Str & str))
{
	for (int i = 0; i<1; i++)   //1 dla testu
	{
		pf(stru[i]);
	}
}

Stack::Stack()
{
	top = 0;
}

bool Stack::is_empty() const
{
	return top == 0;
}

bool Stack::is_full() const
{
	return top == MAX;
}

bool Stack::push(const Str & str)
{
	if (top < MAX)
	{
		stru[top].payment = str.payment;
		strcpy(stru[top].fullname,str.fullname);
		top++;
		return true;
	}
	else return false;
}

bool Stack::pop(Str & str)
{
	if(top > 0)
	{
		--top;
		str.payment = stru[top].payment;
		strcpy(str.fullname, stru[top].fullname);
		return true;
	}
	else return false;
}

void Stack::show_list() const
{
	for(int i = 0; i < top; i++) std::cout<<stru[i].fullname<<"\t"<<stru[i].payment<<std::endl;
}

void Stack::sort_list()
{
//	std::cout<<"TOP  "<<top<<std::endl;
	int i = 0;
	while(i < top-1)
	{
		if (stru[i].payment < stru[i+1].payment)
		{
			char pom1[40];
		
			int pom = stru[i].payment;
			strcpy(pom1,stru[i].fullname);
		
			stru[i].payment = stru[i+1].payment;
			strcpy(stru[i].fullname,stru[i+1].fullname);
			
			stru[i+1].payment = pom;
			strcpy(stru[i+1].fullname,pom1);
			
			i = 0;
		}
		else i++;
	}
} 

Proszę spojrzeć na funkcję "funkcja" (oraz "visit"), którą zmieniam wartości elementów klasy. Czy ma to jakiś sens?

spartanPAGE
  • Rejestracja: dni
  • Ostatnio: dni
1

Nie jest to nic bez czego można żyć. Poprawne rozwiązanie to to z użyciem template.
Ale jeśli takie masz wymagania w ćwiczeniu, to spoko.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.