C++ Academy · Lekcja

Mixiny z CRTP

Komponuj zachowanie w czasie kompilacji

Lekcja 3 z 413 kroki

Mixiny z CRTP to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C++ Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C++ Academy zawiera 4 lekcji w sumie.

Czym jest mixin?

Mixin to mała, wielokrotnego użytku jednostka zachowania, którą można skomponować z klasą. W połączeniu z CRTP mixiny dodają funkcjonalność w czasie kompilacji, jednocześnie wywołując metody klasy-gospodarza.

Prosty mixin

Ten mixin dodaje metodę print_twice, która wymaga, aby klasa-gospodarz udostępniała value().

#include <iostream>

template <typename T>
struct PrintTwice {
    void print_twice() const {
        auto v = static_cast<const T*>(this)->value();
        std::cout << v << " " << v << "\n";
    }
};

struct Box : PrintTwice<Box> {
    int value() const { return 7; }
};

int main() {
    Box{}.print_twice();
    return 0;
}

Komponowanie wielu mixinów

Mogą Państwo dziedziczyć jednocześnie po kilku mixinach CRTP, nakładając niezależne zachowania na jedną klasę.

#include <iostream>

template <typename T>
struct Loggable {
    void log() const { std::cout << "log: " << static_cast<const T*>(this)->id() << "\n"; }
};

template <typename T>
struct Resettable {
    void reset() { static_cast<T*>(this)->set(0); }
};

struct Device : Loggable<Device>, Resettable<Device> {
    int v = 5;
    int id() const { return v; }
    void set(int x) { v = x; }
};

int main() {
    Device d;
    d.log();
    d.reset();
    d.log();
    return 0;
}

Mixiny mogą również przechowywać stan

Mixin może zawierać własne składowe danych, które stają się częścią układu pamięci skomponowanego obiektu.

#include <iostream>

template <typename T>
struct Tagged {
    int tag = 0;
    void set_tag(int t) { tag = t; }
    int get_tag() const { return tag; }
};

struct Item : Tagged<Item> {
    const char* name = "item";
};

int main() {
    Item it;
    it.set_tag(42);
    std::cout << it.name << " " << it.get_tag() << "\n";
    return 0;
}

Mixin a zwykłe dziedziczenie

Mixin CRTP różni się od zwykłego dziedziczenia tym, że klasa bazowa może wywoływać metody klasy pochodnej. Zwykłe klasy bazowe nie mogą bez funkcji wirtualnych wywoływać metod, które istnieją wyłącznie w typie pochodnym.

Projektowanie oparte na strategiach

Mixiny umożliwiają projektowanie oparte na strategiach: zachowania są wybierane w czasie kompilacji przez określenie, po których mixinach ma dziedziczyć klasa, podobnie jak std::vector przyjmuje strategię alokatora.

Kolejność i układ pamięci

Podczas układania mixinów kolejność klas bazowych wpływa na kolejność konstrukcji i układ pamięci obiektu. Mixiny powinny być niezależne, aby ich kolejność nie wpływała na poprawność działania.

  • Konstrukcja odbywa się w kolejności deklaracji klas bazowych
  • Należy unikać mixinów zależnych od siebie

Dodawanie mixinu równości

W tym przykładzie mixin tworzy operator!= na podstawie operatora równości klasy-gospodarza.

#include <iostream>

template <typename T>
struct EqualityMixin {
    friend bool operator!=(const T& a, const T& b) { return !(a == b); }
};

struct P : EqualityMixin<P> {
    int x;
    P(int v) : x(v) {}
    friend bool operator==(const P& a, const P& b) { return a.x == b.x; }
};

int main() {
    std::cout << (P(1) != P(2)) << "\n";
    return 0;
}

Warunkowe mixiny

Mixin można dołączyć tylko wtedy, gdy spełniony jest określony warunek, łącząc dziedziczenie z std::conditional i wybierając między rzeczywistym mixinem a pustym odpowiednikiem.

Optymalizacja pustej klasy bazowej

Mixiny, które nie zawierają składowych danych, korzystają z optymalizacji pustej klasy bazowej: kompilator nie przydziela na nie żadnych dodatkowych bajtów, więc układanie wielu bezstanowych mixinów nie zwiększa rozmiaru obiektu.

#include <iostream>

template <typename T>
struct A {};
template <typename T>
struct B {};

struct C : A<C>, B<C> {
    int x;
};

int main() {
    std::cout << (sizeof(C) == sizeof(int)) << "\n";
    return 0;
}

Kiedy warto używać mixinów

Mixiny sprawdzają się szczególnie wtedy, gdy wiele klas potrzebuje tych samych niezależnych zachowań, takich jak logowanie, zliczanie czy porównywanie. Każde zachowanie znajduje się w jednym miejscu, a ich komponowanie nie wiąże się z kosztem w czasie wykonania.

Szybkie sprawdzenie

Proszę sprawdzić, jak dobrze rozumieją Państwo mixiny CRTP.

Podsumowanie

Nauczyli się Państwo tworzyć mixiny za pomocą CRTP.

  • Mixiny komponują niezależne zachowania w czasie kompilacji
  • Mogą wywoływać metody klasy-gospodarza i przechowywać stan
  • Bezstanowe mixiny nie zwiększają rozmiaru obiektu dzięki optymalizacji pustej klasy bazowej
  • Doskonale nadają się do strategii logowania, porównywania i zliczania
Bezpłatny start

Ucz się C++ dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
51
Lekcje
203

Często zadawane pytania

Czy lekcja „Mixiny z CRTP” jest bezpłatna?

Tak — pełny tekst „Mixiny z CRTP” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C++ Academy, przejdź na CoddyKit PRO. Kurs C++ Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Mixiny z CRTP”?

Komponuj zachowanie w czasie kompilacji Ćwiczysz C++ Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C++ Academy?

Nie wymagamy żadnego doświadczenia. C++ Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Mixiny z CRTP”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C++ Academy?

Tak. Każda lekcja C++ Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Idiom CRTP
  2. Polimorfizm statyczny
  3. Mixiny z CRTP
  4. Kiedy używać CRTP
← Powrót do C++ Academy