Сетери и гетери, Конструктор

Сетерите (setters) и гетерите (getters) се клучни алатки за енкапсулација во C++. Со нив, податоците во класата ги чуваме како private (за да бидат заштитени), а до нив пристапуваме преку public методи.

Ова ни овозможува да контролираме како се менуваат вредностите

Пример за класа Student

Еве едноставен пример како се користи овој концепт:

#include <iostream> #include <string> using namespace std; class Student { private: string name; int age; public: // Сетер за име - го менува приватното поле void setName(string n) { name = n; } // Гетер за име - го враќа приватното поле string getName() { return name; } // Сетер со валидација - спречува нелогични податоци void setAge(int a) { if (a > 0) { age = a; } else { cout << "Грешка: Возраста мора да биде позитивен број!\n"; } } // Гетер за возраст int getAge() { return age; } }; int main() { Student s1; s1.setName("Марко"); s1.setAge(20); cout << "Студент: " << s1.getName() << ", Возраст: " << s1.getAge() << std::endl; return 0; }







Конструктор 

 Кога додаваме конструктор, ја правиме класата покомплетна бидејќи овозможуваме објектот да се иницијализира со вредности веднаш штом ќе биде креиран.

Еве еден пример со класа Student каде користиме:
  • Конструктор (за почетни вредности).
  • Сетери (за промена на податоците со проверка).
  • Гетери (за читање на податоците).

#include <iostream>
#include <string>
using namespace std;
class Student {
private:
    string ime;
    int indeks;
    double prosek;
public:
    // КОНСТРУКТОР - Се повикува автоматски при креирање на објектот
    Student(string i, int ind, double p) {
        ime = i;
        indeks = ind;
        // Користиме сетер внатре во конструкторот за да ја провериме валидноста
        setProsek(p);  }

    // СЕТЕРИ (Setters)
    void setIme(string i) {
        ime = i;  }

    void setProsek(double p) {
        if (p >= 6.0 && p <= 10.0) {
            prosek = p;
        } else {
            cout << "Грешка: Невалиден просек (мора да е меѓу 6 и 10). Поставен е на 6.0." << endl;
            prosek = 6.0;
        }    }

    // ГЕТЕРИ (Getters)
  string getIme() { return ime; }
    int getIndeks() { return indeks; }
    double getProsek() { return prosek; }
    // Метод за приказ на информации
    void pecati() {
      cout << "Студент: " << ime << " (Индекс: " << indeks << ") - Просек: " << prosek << endl;
    }
};

int main() {
    // Креирање објект преку конструкторот
    Student s1("Марко Марковски", 201045, 9.2);
    s1.pecati();
    // Обид за внесување невалиден просек преку сетер
    cout << "\nСе обидуваме да поставиме просек 15.0..." << endl;
    s1.setProsek(15.0);
        // Промена на име преку сетер
    s1.setIme("Марко С. Марковски");
    cout << "\nАжурирани податоци:" << std::endl;
    cout << "Име на студент: " << s1.getIme() << endl;
    cout << "Финален просек: " << s1.getProsek() << endl;
    return 0;
}

Наједноставно кажано: Конструкторот е „рецептот“ за тоа како се раѓа еден објект.

Еве ги 3-те клучни правила за конструктор:

  1. Името на конструкторот мора да биде идентично со името на класата.

  2. Нема тип на враќање (не пишуваме ни void, ни int, ништо).

  3. Се повикува автоматски само еднаш — во моментот кога пишуваме Student s1;

Зошто воопшто ни е потребен?

Замисли да правиш објект Student. Ако немаш конструктор, компјутерот ќе резервира меморија, но во променливите ime и indeks ќе има „ѓубре“ (случајни броеви преостанати во меморијата). Конструкторот гарантира дека објектот ќе почне со чисти и точни податоци.

#include <iostream>
#include <string>
using namespace std;

class Student {
public:
string ime;
int indeks;
// 1. Празен конструктор (Default Constructor)
// Ова се случува ако само напишеш: Student s;
Student() {
ime = "Непознато";
indeks = 0;
cout << "Нов студент!" << endl;
}

// 2. Конструктор со параметри
// Ова се случува ако напишеш: Student s("Ана", 123);
Student(string i, int ind) {
ime = i;
indeks = ind;
cout << "Нов студент " << ime << "!" << endl;
} };

int main() {
// Тука автоматски се повикува првиот (празниот) конструктор
Student s1;
// s1.ime сега е "Непознато"
// Тука автоматски се повикува вториот конструктор со вредности
Student s2("Марко", 21105);
// s2.ime сега е "Марко"
return 0;
}

  • Конструкторот е како моментот кога во фабрика го склопуваат телефонот и му ставаат сериски број. Тоа се прави само еднаш.

  • Сетерот е како кога ти подоцна ќе го смениш името на телефонот во менито за Settings. Тоа можеш да го правиш колку пати сакаш.

  • Што треба да запомниш (накратко):

    1. Конструкторот е „Раѓање“: Без него, објектот не знае кој е и што има. Тој ги поставува почетните вредности.

    2. Сетерот е „Промена“: Тој дозволува безбедно да ја смениш вредноста (на пр. да додадеш пари на сметката) откако објектот веќе е создаден.

    3. Гестерот е „Поглед“: Тој само ти кажува колку е вредноста, без да ја менува.

    #include <iostream>
    #include <string>
    using namespace std;
    class BankarskaSmetka {
    private:
        string sopstvenik;
        double balans;
    public:
        // 1. КОНСТРУКТОР: Се извршува САМО КОГА СЕ КРЕИРА СМЕТКАТА
        // Ова е моментот кога клиентот доаѓа во банка и ја отвора сметката.
        BankarskaSmetka(string ime, double pocetenVlog) {
            sopstvenik = ime;
            if (pocetenVlog >= 0) {
                balans = pocetenVlog;}
                else {
                balans = 0; } // Не може да отвори сметка со негативни пари
            
            cout << "--- Smetkata za " << sopstvenik << " e uspeshno kreirana! ---" << endl;
        }
        // 2. СЕТЕР: Се извршува секогаш кога клиентот сака да стави пари
        void uplati(double suma) {
            if (suma > 0) {
                balans += suma;
            cout << "Uspeshna uplata od " << suma << " denari." << endl;
            }      }
        // 3. ГЕТЕР: Се извршува кога клиентот сака да провери колку пари има
        double getBalans() {
            return balans;
        } };

    int main() {
        // ТУКА СЕ ПОВИКУВА КОНСТРУКТОРОТ (еднаш)
        BankarskaSmetka smetka1("Petar", 1000.0);
        // Проверуваме состојба преку ГЕТЕР
        cout << "Momentalna sostojba: " << smetka1.getBalans() << " den." << endl;
        // Менуваме состојба преку СЕТЕР (уплата)
        smetka1.uplati(500.0);
        // Повторно проверуваме преку ГЕТЕР
        cout << "Nova sostojba: " << smetka1.getBalans() << " den." << endl;
        return 0;
    }

    Корисникот внесува податоци преку тастатура 

    #include <iostream>
    #include <string>
    using namespace std;

    class BankarskaSmetka {
    private:
        string sopstvenik;
        double balans;
    public:
        BankarskaSmetka(string ime, double pocetenVlog) {
            sopstvenik = ime;
            if (pocetenVlog >= 0)
                balans = pocetenVlog;
            else
                balans = 0;
            cout << "--- Smetkata za " << sopstvenik << " e uspeshno kreirana! ---" << endl;
        }
        void uplati(double suma) {
            if (suma > 0) {
                balans += suma;
                cout << "Uspeshna uplata od " << suma << " denari." << endl;
            }     }

        double getBalans() {
            return balans;     }
    };

    int main() {
        string ime;
        double pocetenVlog;
        double uplata;
        cout << "Vnesi ime na sopstvenik: ";
        cin >> ime;
        cout << "Vnesi poceten vlog: ";
        cin >> pocetenVlog;
        BankarskaSmetka smetka1(ime, pocetenVlog);
        cout << "Momentalna sostojba: " << smetka1.getBalans() << " den." << endl;
        cout << "Vnesi suma za uplata: ";
        cin >> uplata;
        smetka1.uplati(uplata);
        cout << "Nova sostojba: " << smetka1.getBalans() << " den." << endl;
        return 0;
    }

    No comments: