NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Definice vlastniho kontejneru

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Michal Hadraba:11.3.2023 22:38

Chci vytvorit vlastni kontejnerovou tridu, napr. jako rozsireni tridy vector tak, aby byla pouzitelna v cyklu for:

For(auto prvek : container)

Jake metody musi obsahovat, aby to fungovalo?

Zkusil jsem: Hledal jsem na netu... marne.

Chci docílit: Potrebuji tridu, jejiz zakladem je kontejner plus ma nejake dalsi parametry. Napriklad polygon, skladajici se z bodu, ktera ma mavic barvu, atd., a chtel bych k ni pristupovat zpusobem

For(auto bod : krivka)
 
Odpovědět
11.3.2023 22:38
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Hadraba
DarkCoder:12.3.2023 12:11

Třeba něco takovéto:

#include <iostream>
#include <vector>
#include <string>

class Point {
public:
        Point(int x, int y, std::string color) : x(x), y(y), color(color) {}
        int x, y;
        std::string color;
};

class Polygon {
public:
        Polygon() {}
        void add_point(int x, int y, std::string color);
        std::vector<Point>::const_iterator begin() const;
        std::vector<Point>::const_iterator end() const;
private:
        std::vector<Point> points;
};

void Polygon::add_point(int x, int y, std::string color) {
        points.push_back(Point(x, y, color));
}

std::vector<Point>::const_iterator Polygon::begin() const {
        return points.begin();
}

std::vector<Point>::const_iterator Polygon::end() const {
        return points.end();
}

int main() {
        Polygon poly;
        poly.add_point(0, 0, "red");
        poly.add_point(10, 0, "green");
        poly.add_point(10, 10, "blue");
        poly.add_point(0, 10, "yellow");

        for (const auto& point : poly) {
                std::cout << point.x << ", " << point.y << ", " << point.color << std::endl;
        }

        return 0;
}
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
12.3.2023 12:11
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Michal Hadraba:12.3.2023 14:28

Asi jo, do. To znamená, že stačí begin() a end()? A jak ten vestaveny "for" pozna krok? Step?

 
Nahoru Odpovědět
12.3.2023 14:28
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Hadraba
DarkCoder:12.3.2023 15:08

"Range-based for cyklus" nepracuje s explicitním krokem jako klasický for cyklus. Místo toho se při každém průchodu cyklem automaticky získává další prvek kontejneru, na kterém se provádí iterace. Tento typ cyklu je zkrácenou a jednodušší verzí klasického for cyklu pro iteraci přes prvky v kontejneru.

for (const auto& point : poly) {
    std::cout << point.x << ", " << point.y << ", " << point.color << std::endl;
}

Konkrétně v této konstrukci se cyklus iteruje přes prvky objektu poly, který je instance třídy Polygon. Tento cyklus v každém průchodu přiřadí do proměnné point další prvek z poly. Celkově tedy tento cyklus projde každý prvek v poly, který je vektor objektů typu Point, a vypíše jeho x-ovou a y-ovou souřadnici a barvu na standardní výstup.

Nahoru Odpovědět
12.3.2023 15:08
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Hadraba
DarkCoder:12.3.2023 15:15

Zde pak je vypsání kontejneru pomocí for s iterátory:

for (auto it = poly.begin(); it != poly.end(); ++it) {
    std::cout << it->x << ", " << it->y << ", " << it->color << std::endl;
}
Nahoru Odpovědět
12.3.2023 15:15
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Michal Hadraba:12.3.2023 16:19

A nebo takto to je takové více systémové, ne? Ale princip už je mi jasný.

using namespace std;

class Point{
public:
        Point(int x, int y, std::string color) : x(x), y(y), color(color) {}
        int x, y;
        std::string color;
};

class CPolygon : private std::vector<Point>
{
public:
    CPolygon() {}
    void push_back(const int x, const int y, std::string color);
    void push_back(const Point pt);
    CPolygon::const_iterator begin() const;
    CPolygon::const_iterator end() const;

};

void CPolygon::push_back(const int x, const int y, std::string color) {
    vector<Point>::push_back(Point(x, y, color));
}

void CPolygon::push_back(const Point pt) {
    vector<Point>::push_back(pt);
}

CPolygon::const_iterator CPolygon::begin() const {
    return std::vector<Point>::begin();
}

CPolygon::const_iterator CPolygon::end() const {
    return std::vector<Point>::end();
}
 
Nahoru Odpovědět
12.3.2023 16:19
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Hadraba
DarkCoder:12.3.2023 17:48

Ano, je možné dědit třídu vector a přidat novou implementaci. Nejsem zastánce tohoto obalování, kde je dost věcí kvůli dědičnosti při pohledu na třídu skryto. V tomto případě by stačilo pracovat s vektorem jako s vektorem bodů - std::vector<Point>.

Nahoru Odpovědět
12.3.2023 17:48
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.