Programowanie obiektowe - architektura przykladowego programu

0

Witam, osiagnalem pewien poziom w programowaniu proceduralnym w C++ i teraz chcialem sprobowac programowania obiektowego w C++. Zaczynam je od zera. Przeczytalem cale dwa tomy Symfonii Grebosza i wszystko tam rozumialem(nie twierdze, ze sam bym wszystko napisal bez problemu, ale rozumialem). Moja metoda nauki to programowanie na Spoju. Mam zaliczone wiekszosc programow na poziomie Latwy na Spoju i chcialem przerabiac je na obiektowe dla nauki tego podejscia. Pierwsze 10 zadan napisalem tworzac tylko jeden rodzaj obiektu w kazdym zadaniu i sam nie wiem, czy za latwo to poszlo, czy te programy wiecej nie wymagaja. Ale przy tym zadaniu naszly mnie powazne watpliwosci: https://pl.spoj.com/problems/GLUTTON/ Otoz nie chcialbym pisac obiektowo byle jak, ze jak dziala, a pewnie jest pelno bledow w strukturze programu, to nic. Uwazam, ze utrwalanie blednych programow jesli chodzi o architekture/strukture mija sie z celem. Myslac nad tym zadaniem wpadlem na kilka roznych pomyslow i nie wiem, ktory jest najblizszy poprawnego podejscia.
Prosze o wskazanie numeru, ktore podejscie wydaje sie najlepsze/poprawne z jakims chociaz krotkim wytlumaczeniem dlaczego albo przedstawienie swoich propozycji, jesli zadne:

  1. Wyodrebnienie trzech klas: obzartuchy, ciastka i pudelka. Tworzenie kolejnych obiektow obzartuchy ze zmienna czasZjedzeniaCiastka; zmienna statyczna w obzartuchy lacznaIloscZjedzonychCiastek oraz metoda statyczna sumujaca je, tak samo ze zmienna lacznaIloscZuzytychPudelek. Obiekt ciastko wewnatrz klasy pudelka. Tworzenie obiektu pudelko dla kazdego obzartucha i obliczanie w nim ilosci ciastek i ilosci pudelek dla konkretnego obzartucha.
  2. Wyodrebnienie jednej klasy obzartuch z danymi skladowymi:czasZjedzeniaCiastka, stala iloscSekundWDobie, zmienne: iloscCiastek, iloscPudelek, dana skladowa statyczna lacznaIloscCiastek, dana skladowa statyczna lacznaIloscPudelek oraz metody. Tworzenie nowego obiektu dla kazdego obzartucha i na koniec utworzenie obiektu obzartuch z zsumowanymi wartosciami ilosc ciasteczek i ilosc pudelek, wyliczanych sumujac zmienne z obiektow obzartuchy.
0

plik obzartuch.h


class obzartuch
{
	int iloscPudelek;
	int czasNaJednoCiastko;
	int iloscCiastek;
	const int doba;
	int iloscCiastekWPudelku;

public:
	obzartuch();

	obzartuch(int zero);
	
	void obliczIloscCiastek();
	int ustawIloscCiastek(int dodaj);
	int sprawdzIloscCiastek();

	void obliczIloscPudelek(int m);
	int ustawIloscPudelek(int dodaj);
	int sprawdzIloscPudelek();

};

plik obzartuch.cpp

#include "obzartuch.h"

#include <iostream>

using namespace std;

obzartuch::obzartuch():iloscPudelek(0),czasNaJednoCiastko(0),iloscCiastek(0),doba(86400),iloscCiastekWPudelku(0) {

	cin >> czasNaJednoCiastko;

	obzartuch::obliczIloscCiastek();
}

obzartuch::obzartuch(int zero) : iloscPudelek(0), czasNaJednoCiastko(0), iloscCiastek(0), doba(86400), iloscCiastekWPudelku(0) {

}

int obzartuch::sprawdzIloscCiastek() {

	return iloscCiastek;
}

void obzartuch::obliczIloscCiastek() {

	iloscCiastek = doba / czasNaJednoCiastko;

}

int obzartuch::ustawIloscCiastek(int dodaj) {

	iloscCiastek += dodaj;

	return iloscCiastek;
}

void obzartuch::obliczIloscPudelek(int m) {

	iloscPudelek += iloscCiastek / m;

}

int obzartuch::ustawIloscPudelek(int dodaj) {

	iloscPudelek += dodaj;

	return iloscPudelek;
}

int obzartuch::sprawdzIloscPudelek() {

	return iloscPudelek;
}

plik zrodlo.cpp

#include "obzartuch.h"

#include <iostream>

using namespace std;

int main() {

	int t = 0;  //liczba testow

	cin >> t;

	if (t > 0) {

		for (int i = 0; i < t; i++) {

			const int dobaWSekundach = 86400;

			int n, m;   // n >= 1 && n <= 10000,  m >=1 && m <=1000000000

			cin >> n;
			cin >> m;

			obzartuch* ob = new obzartuch[n]; //konstruktor wczytuje czas zjedzenia ciastka w sekundach dla kazdego obzartucha

			obzartuch wszyscy(0);				//utworzenie obiektu wszyscy, tutaj beda sumaryczne wartosci
			for (int j = 0; j < n;j++) wszyscy.ustawIloscCiastek(ob[j].sprawdzIloscCiastek());

			if (wszyscy.sprawdzIloscCiastek() % m != 0) wszyscy.ustawIloscPudelek(1);
			
			wszyscy.obliczIloscPudelek(m);

			cout << wszyscy.sprawdzIloscPudelek() << "\n";
			
		}
	}

	return 0;
}
2

Pytasz o architekturę, trudno przy jednej klasie mówić o architekturze. Kilka uwag, prawdopodobnie nie wszystkie

  1. Wczytywanie w konstruktorze ze strumienia to nie jest dobre (z kilku powodów, ale by bardzo długo było)
  2. w metodach ustawXxxxxx dodawanie jest strasznym dziwolągiem. Nazwa "ustaw" zobowiązuje. Jeśli to przygrywka do obiektu "wszyscy", to jest zdecydowanie ŹLE.
  3. I tu wracając do architektury, Zagadnienie "wszyscy" powinno być rozwiązane inną klasą (być może obie ze wspólnego interfejsu / klasy abstrakcyjnej). Jabłko nie jest koszykiem jabłek (ani pomarańczą). Dla kasy Wszyscy możesz zaimplementować operator += Obżartuch
    Pytasz o dobry styl, to obecnie jest zdecydowanie źle.
  4. Liczne problemy implementacyjne / koderskie (powołane zmienne / pola nigdy nie zainicjowane.
    5 zmienne nazywaj tak, aby komentarz nie był potrzebny.
0
AnyKtokolwiek napisał(a):

Pytasz o architekturę, trudno przy jednej klasie mówić o architekturze. Kilka uwag, prawdopodobnie nie wszystkie

  1. Wczytywanie w konstruktorze ze strumienia to nie jest dobre (z kilku powodów, ale by bardzo długo było)
  2. w metodach ustawXxxxxx dodawanie jest strasznym dziwolągiem. Nazwa "ustaw" zobowiązuje. Jeśli to przygrywka do obiektu "wszyscy", to jest zdecydowanie ŹLE.
  3. I tu wracając do architektury, Zagadnienie "wszyscy" powinno być rozwiązane inną klasą (być może obie ze wspólnego interfejsu / klasy abstrakcyjnej). Jabłko nie jest koszykiem jabłek (ani pomarańczą). Dla kasy Wszyscy możesz zaimplementować operator += Obżartuch
    Pytasz o dobry styl, to obecnie jest zdecydowanie źle.
  4. Liczne problemy implementacyjne / koderskie (powołane zmienne / pola nigdy nie zainicjowane.
    5 zmienne nazywaj tak, aby komentarz nie był potrzebny.
Dziekuje za odpowiedz. Co do punktu 4 to uzywam listy inicjalizacyjnej, czyli sie nie zgadzam. A reszta zakladam, ze masz racje. Ogromnie bylbym wdzieczny, gdybys napisal mi ten program (kod, tylko obiektowo). Rozumiem, ze to jest dla Ciebie bardzo latwe, a ja napotkalem na liczne problemy i to bylaby dla mnie swietna nauka.
0

Dodam od siebie z tego co widzę. Masz new, a brak delete (inna sprawa, że obecnie wytyczne mówią o minimalizowaniu użycia czystych wskaźników).
Książka Grębosza kilkanaście lat temu była ok, ale teraz od jakiś 10 lat jest ona bardzo nieaktualna. Autor też to zrozumiał i napisał nową (jak porównywałem, trochę rozdziałów jest przepisanych, ale tylko część). Czas też poznać trochę od innej strony C++, ale z drugiej strony przyjąć, że jeśli używamy już czystych wskaźników, to pilnujemy, by pamięć zwalniać po tym jak ją przydzielimy.

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