Menu
Coddy logo textTech

Wiązania strukturalne

Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 88 z 104.

Wiązania strukturalne, wprowadzone w C++17, pozwalają rozpakować wiele wartości z tablic, par, krotek lub struktur do osobnych nazwanych zmiennych w jednej deklaracji. Dzięki temu kod jest bardziej przejrzysty i czytelny podczas pracy ze złożonymi danymi.

Składnia używa auto z nawiasami kwadratowymi zawierającymi nowe nazwy zmiennych:

#include <iostream>
#include <map>
#include <tuple>

int main() {
    // Rozpakowywanie pary
    std::pair<std::string, int> person{"Alice", 25};
    auto [name, age] = person;
    std::cout << name << " is " << age << "\n";
    
    // Rozpakowywanie krotki
    std::tuple<int, double, char> data{42, 3.14, 'X'};
    auto [num, pi, letter] = data;
    
    // Rozpakowywanie w pętlach for opartych na zakresach
    std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
    for (const auto& [student, score] : scores) {
        std::cout << student << ": " << score << "\n";
    }
}

Więzy strukturalne działają również z tablicami i własnymi strukturami, które mają publiczne składowe:

struct Point {
    double x;
    double y;
};

Point getOrigin() { return {0.0, 0.0}; }

int main() {
    auto [x, y] = getOrigin();
    
    int arr[3] = {1, 2, 3};
    auto [a, b, c] = arr;
}

Możesz użyć auto& lub const auto&, aby powiązać przez referencję, unikając kopiowania i umożliwiając modyfikowanie oryginalnych wartości w razie potrzeby. Ta funkcja jest szczególnie przydatna podczas iterowania po kontenerach STL lub obsługi funkcji zwracających wiele wartości.

challenge icon

Wyzwanie

Łatwy

Zbudujmy analizator ocen uczniów, który pokazuje możliwości wiązań strukturalnych. Stworzysz system przetwarzający dane uczniów i kursów, wykorzystując wiązania strukturalne do eleganckiego rozpakowywania par, krotek i struktur w całym kodzie.

Rozmieścisz swój kod w trzech plikach:

  • Student.h: Zdefiniuj strukturę Student z publicznymi polami zawierającymi imię i nazwisko ucznia (std::string), identyfikator (int) i GPA (double). Utwórz też funkcję o nazwie createStudent, która przyjmuje imię i nazwisko, identyfikator oraz GPA, a następnie zwraca strukturę Student.
  • GradeUtils.h: Utwórz funkcje pomocnicze do przetwarzania ocen.

    Zdefiniuj funkcję getGradeInfo, która przyjmuje wynik liczbowy (liczbę całkowitą) i zwraca obiekt std::tuple zawierający trzy wartości: ocenę literową (std::string), punkty za ocenę (double) oraz informację, czy ocena jest zaliczająca (bool). Zastosuj następującą skalę ocen:

    • 90+ : "A", 4.0, true
    • 80-89: "B", 3.0, true
    • 70-79: "C", 2.0, true
    • 60-69: "D", 1.0, true
    • Poniżej 60: "F", 0.0, false

    Zdefiniuj również funkcję makeScorePair, która przyjmuje nazwę kursu (std::string) i wynik (int), a następnie zwraca obiekt std::pair zawierający te wartości.

  • main.cpp: Wczytaj cztery dane wejściowe:
    1. Imię i nazwisko ucznia (ciąg znaków)
    2. Identyfikator ucznia (liczba całkowita)
    3. Nazwa kursu (ciąg znaków)
    4. Wynik (liczba całkowita)

    Używaj wiązań strukturalnych w całej funkcji głównej:

    1. Wywołaj createStudent, przekazując imię i nazwisko, identyfikator oraz zastępczą wartość GPA równą 0.0. Użyj wiązań strukturalnych, aby rozpakować zwróconą strukturę na poszczególne zmienne, a następnie wypisz: Student: [name] (ID: [id])
    2. Wywołaj makeScorePair, przekazując nazwę kursu i wynik. Użyj wiązań strukturalnych, aby rozpakować parę, a następnie wypisz: Course: [course], Score: [score]
    3. Wywołaj getGradeInfo, przekazując wynik. Użyj wiązań strukturalnych, aby rozpakować wszystkie trzy elementy krotki, a następnie wypisz:
      Grade: [letter]
      Points: [points]
      Passing: [yes/no]
      (Wypisz "yes", jeśli ocena jest zaliczająca, albo "no", jeśli nie jest)

Na przykład dla danych wejściowych Alice, 1001, Math i 85:

Student: Alice (ID: 1001)
Course: Math, Score: 85
Grade: B
Points: 3
Passing: yes

Dla danych wejściowych Bob, 2002, Physics i 55:

Student: Bob (ID: 2002)
Course: Physics, Score: 55
Grade: F
Points: 0
Passing: no

Pamiętaj, aby w razie potrzeby dołączyć <tuple> i <utility>. Najważniejsze jest to, że wiązania strukturalne pozwalają rozpakować typy złożone, pary, krotki i struktury na nazwane zmienne w jednej, czytelnej deklaracji.

Spróbuj swoich sił

#include <iostream>
#include <string>
#include "Student.h"
#include "GradeUtils.h"

int main() {
    // Wczytaj dane wejściowe
    std::string studentName;
    int studentId;
    std::string courseName;
    int score;
    
    std::cin >> studentName;
    std::cin >> studentId;
    std::cin >> courseName;
    std::cin >> score;
    
    // TODO: Wywołaj createStudent z imieniem, identyfikatorem i tymczasową wartością GPA równą 0.0
    // Użyj wiązań strukturalnych, aby rozpakować strukturę: auto [name, id, gpa] = ...
    // Wypisz: Student: [name] (ID: [id])
    
    
    // TODO: Wywołaj makeScorePair z nazwą kursu i wynikiem
    // Użyj wiązań strukturalnych, aby rozpakować parę: auto [course, sc] = ...
    // Wypisz: Course: [course], Score: [score]
    
    
    // TODO: Wywołaj getGradeInfo z wynikiem
    // Użyj wiązań strukturalnych, aby rozpakować krotkę: auto [letter, points, passing] = ...
    // Wypisz:
    // Grade: [letter]
    // Points: [points]
    // Zaliczenie: [yes/no] (wypisz "yes", jeśli passing ma wartość true, lub "no", jeśli ma wartość false)
    
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C++ online