Loading...
Jovanna avatar Jovanna 186 Точки

Nested classes

Здравейте, опитвам се да направя включен клас, но иска вероятно и дифолтни конструктори, и/или , включеният клас да се подава в конструктора на външния по референция и const, което не ми е ясно как става. 

Не знам дали и конструктурите съм направила добре.

Също, ме накара да си направя полетата на включения клас публични, за да мога да работя с тях от методите на външния клас (?)

Вход: подава се информация за градини, в които има различни видове цветя, като особеното е че всеки отделен вид цвете има различни височини на израстване , които ги вкарвам за всеки вид цвете в map<double, int> ( височини : брой на цветята от тази дължина) за съответния вид, в съотв. градина.

GardenA  flowerFFF  23,3  20

GardenD  flowerER  11,8  150

GardenE  flowerC  5,70  80

GardenA  flowerFFF  10  300

class FlowersInGarden
        {
            class Flower
            {
            public:
                std::string flowerName; 
                std::map<double, int> dataFlower;  //hight, quantity
                
                Flower(std::string flowerName, double hight, int quantity) :
                    flowerName(flowerName)                    
                {
                    this->dataFlower[hight] = quantity;
                }
            };
        private:
            std::string nameGarden;           

            std::list<Flower> dataLiGardenFlowers;

        public:
            FlowersInGarden(std::string gardenName, std::string flowerName, double hight, int quantity) :
                nameGarden(gardenName)                
            {                
                this->dataLiGardenFlowers.push_back({ flowerName, hight, quantity });
            }

};

Тагове:
0
C++ Fundamentals
georgi.stef.georgiev avatar georgi.stef.georgiev 921 Точки

Здравей,

Не разбирам напълно какво питаш. Така написан кодът ти се компилира и прави това, което изглежда му е зададено.

Относно защо нещата във вътрешния клас, които външния иска да достъпи, трябва да са public - просто в C++ е така, всяко поле в един клас, което искаш да достъпиш от друго място (било то друг клас, друга функция, или клас който "обвива" въпросния клас), трябва да е public. Може би се бъркаш от Java - там външния клас може да достъпва всичко на вътрешния, но в C++ просто не е такава концепцията. С две думи, ако в C++ искаш да достъпиш нещо от извън скобите на класа, то трябва да е public, толкова (с изключение на friend класове/функции).

Сега относно самата ти архитектура тук, има няколко неща, които не ми харесват съвсем, или ми се струват излишни:

- имаш class Flower, името му твърди, че той държи информацията за ЕДНО цвете, а в същото време имаш в него map (в който пазиш само един запис - защо просто не направиш две полета, едно което ти пази височината и друго с бройката?) който предполага, че всъщност този клас пази информация за много цветя. 

- конструкторът на Flower може да го създаде само с един запис за височина на цветя и бройката им, а най-вероятно се опитваш да можеш да запишеш данни за много видове цветя. Ако искаш така да го изградиш, най-вероятно е ти трябва някакъв метод, който добавя запис височина->бройка, и той да се вика от отвън

- на няколко места полетата ти повтарят името на класа. Ако класът ти се казва Flower, няма смисъл полето му да се казва flowerName - само name би било достатъчно, подразбира се, че е името на цветето

- относно това поле, пак имаме проблем с това, което искаш да пазиш във Flower. Имаш map за много цветя, обаче имаш едно поле за име на цвете. Последно какво пази това нещо, едно цвете с името му, или много цветя?

- защо ти е изобщо да имаш един клас в друг клас? Не че е задължително грешно, но какво печелиш от това в тази задача, освен че скриваш дефиницията на Flower в дефиницията на FlowersInGarden? Струва ми се, че си ги направила, защото градината съдържа цветя. Обаче не е нужно един клас да е дефиниран в друг клас, за да го ползваш за полета на втория - по същия начин както ако направиш Person клас, спокойно можеш да правиш полета от тип string (примерно името му), няма нужда да молиш C++ комитета да дойде и да дефинира string класа вътре в твоя Person.

Като цяло структурата ти е малко объркана, изглежда не си си изчистила съвсем идеята какво искаш да направиш. Опитала си се да решиш наведнъж цялата задача, вместо да направиш класове за отделните компоненти на задачата. Като цяло не се прави "клас за задачата" - както имаш ти клас градина в тази ситуация.

 

Хайде да видим текста на задачата пак - какви "обекти" са ти описали в условието?

- Вид цвете. Обаче вид цвете е малко подвеждащо в случая - изглежда все едно един вид цвете има име и височина до която израства този вид - да ама не, защото по-надолу във входа виждаме вид цветя със същото име обаче различна височина. В такъв случай по-скоро това е група цветя (предполагаемо в една градина може да има няколко групи от един и същи вид, обаче пораснали различно високо). Тоест имаме FlowerGroup, като в него имаме speciesName (или typeName или каквото там решиш за име на "породата" цветя), height и count. Няма нужда от map-ове тук, просто имаме едно описание на едничка група цветя, която пази всичката информация за една група, без градинната част. Тоест дотук от входа пазим неща подобни на { "flowerFFF", 23.3, 20 }.

- Имаме градина. Градината си има име. Освен това градината има цветя в нея. Обаче тези цветя на входа ни ги дават по групи. Като групата която си дефинирахме отгоре. Тоест в една градина има list или vector от обекти от класа дето описахме отгоре. Тоест във всяка градина има { string name; vector<FlowerGroup> flowerGroups; }. Оттук нататък ако искаш да търсиш бързо всички групи от един и същи вид цвете, можеш този vector да го направиш на map<string, vector<FlowerGroup> > - съответно ключът ще е името на видът, а стойността ще са всички групи от цветя с това име. За примерните входни данни, при GardenA ще имаш един map с една стойност "flowerFFF" -> vector { FlowerGroup{"flowerFFF", 23.3, 20}, FlowerGroup{"flowerFFF", 10, 300} } (това е псевдокод разбира се). Тоест имаме class Garden { string name; map<string, vector<FlowerGroup> > flowerGroupsByName; }

- Няма значение дали Flower е дефиниран вътре в Garden или не, ама ми се струва, че ще е по-лесно да не е, за да можем по-лесно да създаваме Flower обекти (иначе трябва да минаваме през Garden всеки път).

- Оттук нататък имаме много на брой градини. Значи vector<Garden>, обаче ако искаме бързо да ги търсим по име, е добре да ги пазим в един map. Тоест map<string, Garden> gardensByName, където ключът е името на градината, а стойността е самата градина.

- Сега, понеже за една градина изглежда в различни моменти ни добавят цветя, това означава, че не можем да очакваме конструктора да я създаде изцяло. Най-лесно да го оставим празен, а да имаме метод addFlowerGroup(FlowerGroup g), който някак добавя тази група вътре в съответната градина. Самия FlowerGroup има смисъл да има конструктор, който го инициализира изцяло, защото всяка група я получаваме напълно (при "GardenA flowerFFF 23.3 20", имаме пълната информация за групата - "flowerFFF 23.3 20", и просто трябва да я създадем). Оттам нататък просто четем името на градината от входа currentGardenName, четем групата цветя currentFlowerGroup, и правим gardensByName[currentGardenName].addFlowerGroup(currentFlowerGroup). Понеже operator[] създава default елемент ако не го намери, първия път като добавяме за GardenA такава ще бъде създадена празна (стига да имаш правилния default constructor) и след това върху тази празна градина ще бъде извикан метода addFlowerGroup. Следващия път пък ще се добави на съществуващата градина.

Горе-долу това ти е архитектурата, остава да имплементираш детайлите на самите операции. И вече ако има нещо друго в задачата, да го изпълниш и него с така организираните данни.

Поздрави,

Жоро

1
Jovanna avatar Jovanna 186 Точки

Гениално!

Това, за бързината на работа на кода, си е много важно. Кави правила да се следват за бързодействие на код, за да конструираме правилно контейнери, обекти, включени/или не класове, би ли дал съвет?

Иначе, това е условието, точно което имплементираш, има много градини (с различни имена), като във всяка има много цветя (с различни имена/видове), и всяко цвете е на различен етап от израстване (с различна височина).

Много благодаря!!

Поздрави 

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.