-
Număr conținut
60 -
Înregistrat
-
Ultima Vizită
Alte grupuri
LCS PREMIUM
Despre NEFERPITOU
- Dată Naștere 04.01.2000
Câmpuri de profil
-
Titlul de membru
#mostHated.
Configurații server
-
Server & Games
ESL
Vizitatori Recenți Profil
553 citiri profil
Realizările lui NEFERPITOU
-
* Obiective ** Prezentare si Implementare a mecanismului de supraincarcare a operatorilor de citire si scriere !! ** Prezentare ** Prin obiectele "cin" sau "cout" putem citi/afisa diverse tipuri de date (intregi,siruri de caractere,numere reale etc.) prin supraincarcarea operatorilor "<<" && ">>" . include <iostream> using namespace std; int main() { // cout , cin , endl --> SUNT OBIECTE // cout --> apartine clasei ostream (Pentru Afisare) --> S-a Supraincarcat Operatorul "<<" // cin --> apartine clasei istream (Pentru Citire) --> S-a Supraincarcat Operatorul ">>" cout << 5 + 7 << endl; // Asta ne afiseaza 12 } "cin" reprezinta obiect din clasa istream (de citire) ; "cout" reprezinta obiect din clasa ostream (de scriere) . Utilizand acest concept , putem sa ne construim pentru obiectele noastre , mecanisme personalizate(unice) pentru afisare (scriere "<<") si inserare (citire ">>") . Totusi , pentru a adapta citirea si scrierea pentru obiectele noastre , trebuie sa supraincarcam , in clasa noastra , atat operatori de citire(">>") cat si scriere ("<<") . ** Supraincarcarea Operatorului de Scriere ** Dorim sa efectuam o operatiune de afisare a obiectului folosind supraincarcarea operatorului "<<" Declam functia cu operatorul supraincarcat : // user.h class User{ /// Operatori friend std::ostream& operator<<(std::ostream& output,User& const user); // Operator de scriere } NOTA 1* : Primeste ca argument atat obiectul de scriere ("cout") din clasa "ostream" cat si obiectul din clasa noastra , pe care dorim sa l afisam !! NOTA 2* : Pentru ca foloseste un obiect strain (obiectul de afisat) , este necesar sa declaram functia ca fiind una prietena . SAU , o alta varianta (fara sa o declari prietena) ar fi sa o declari si implementezi in afara clasei . NOTA 3* : Se returneaza continutul pentru afisare . Urmeaza implementarea acestuia : // user.cpp std::ostream& operator<<(std::ostream& output, User& const user) { // DOAR AFISAM CAMPURILE OBIECTULUI output << "\n{" << "\nID Utilizator : " << user.id << " ,\n" // Acces ID FARA GETTER << "Nume Utilizator : " << user.username << " ,\n" // Acces Username FATA GETTER << "Adresa Mail : " << user.email << " ,\n" // Acces Email FARA GETTER << "Parola Utilizator : " << user.password << " ,\n" // Acces Parola FARA GETTER << "Numar Posturi : " << user.nrPosts << ", \n" // Acces la Nr Posturi FARA GETTER << "STATUS BANAT : " << (user.isBanned ? "ESTE INTERZIS " : "NU ESTE INTERZIS") << " PE LEAGUECS!!, \n }"; return output; // Returnam obiectul de afisat } In final , afisam in programul principal , trei obiecte : #include "User.h" // Includem Clasa de Utilizatori int main() { User user1("Alin", "alin@gmail.com", "alipassword"), user2, user3(user1); // Declaram 3 obiecte (unu implicit , unu explicit , unu clona) . std::cout << user1 << '\n' << user2 << "\n" << user3 << "\n"; } /*** AFISAJ { ID Utilizator : 0 , Nume Utilizator : Alin , Adresa Mail : alin@gmail.com , Parola Utilizator : alipassword , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 1 , Nume Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 0 , Nume Utilizator : Alin , Adresa Mail : alin@gmail.com , Parola Utilizator : alipassword , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } ***/ ** Supraincarcarea Operatorului de citire ** Per asamblu , implementarea este , oarecum , similara cu cea de sus , difera prin faptul ca se efectueaza o operatiune inversa a acelei de sus . Declaram functia de citire in interiorul clasei : // user.h #include <stdio.h> // Pentru afisare la fiecare camp class User{ // Restu Codului /// Operatori Citire & Scriere friend std::ostream& operator<<(std::ostream& output,User& const user); // Declaram Operatorul de Scriere friend std::istream& operator>>(std::istream& input, User& user); // Declaram Operatorul de Citire // NOTA ** : NU ESTE REFERINTA CONSTANTA DEOARECE MODIFICAM DATELE OBIECTULUI !!! } Implementare Operator de Citire , folosind continutul de la tastatura : std::istream& operator>>(std::istream& input, User& const user) { char bufferLine[64]; // Continut temporar (Pana la 64 de caractere) printf_s("DATI-MI NUMELE DE UTILIZATOR:"); input.getline(bufferLine, sizeof(bufferLine)); // Am preluat numele de la tastatura StringLGCS::allocAndFetchString(&user.username, bufferLine); printf_s("DATI-MI ADRESA DE MAIL:"); input.getline(bufferLine, sizeof(bufferLine)); // Am preluat email de la tastatura StringLGCS::allocAndFetchString(&user.email, bufferLine); printf_s("DATI-MI PAROLA DE UTILIZATOR:"); input.getline(bufferLine, sizeof(bufferLine)); // Am preluat parola de la tastatura StringLGCS::allocAndFetchString(&user.password, bufferLine); printf_s("DATI-MI NUMARUL DE POSTURI :"); input.getline(bufferLine, sizeof(bufferLine)); // Am preluat numarul de posturi user.nrPosts = atoi(bufferLine); // Convertim si atribuim numarul de posturi printf_s("ESTE BANAT?(da/nu)"); input.getline(bufferLine, sizeof(bufferLine)); // Preluam daca este banat sau nu if (!strcmp(bufferLine, "da") || !strcmp(bufferLine, "yes")) // Daca avem una dintre aceste doua variante user.isBanned = true; // E BANAT else user.isBanned = false; // ALT INPUT return input; } Pe final , citim (de la tastatura) si afisam un obiect : #include "User.h" // Includem Clasa de Utilizatori int main() { User user1("Alin", "alin@gmail.com", "alipassword"), user2, user3(user1); // Declaram 3 obiecte (unu implicit , unu explicit , unu clona) . // Aplicam la al doilea obiect (cel implicit) , o inserare prin tastatura std::cout << "INSERAM DATELE UTILIZATORULUI : " << std::endl; std::cin >> user2; // CITIM OBIECTUL std::cout << user2; // AFISAM OBIECTUL } /******** REZULTAT INSERAM DATELE UTILIZATORULUI : DATI-MI NUMELE DE UTILIZATOR:ALIN DATI-MI ADRESA DE MAIL:alin.ngr@gmail.com DATI-MI PAROLA DE UTILIZATOR:ALINPAROLA DATI-MI NUMARUL DE POSTURI :43 ESTE BANAT?(da/nu)da { ID Utilizator : 1 , Nume Utilizator : ALIN , Adresa Mail : alin.ngr@gmail.com , Parola Utilizator : ALINPAROLA , Numar Posturi : 43, STATUS BANAT : ESTE INTERZIS PE LEAGUECS!!, } ******/
-
** Obiective ** Prezentarea Conceptului de Supraincarcare a Operatorilor ** Supraincarcarea Operatorilor ** Supraincarcarea Operatorilor reprezinta un mecanism strict C++ , ce ne permite sa efectuam diverse operatiuni asupra obiectelor . Toti operatori pot fi supraincarcati , cu exceptia : operatorul "sizeof" ; operatorul de rezolutie ("::") ; operatorul "typeid" ; operatorul "ternary" ("? :") ; operatorul de selectie (". , .*") . De asemenea , nu putem declara/modifica noi versiuni de operatori (de exemplu , sa declaram operator**(int) pentru ridicarea la puterea a 2) sau sa intervenim asupra prioritati fata de alt operator , asociativitati sau cardinalitatii . ** O Mica Demonstratie ** // user.h class User{ // restu codului /// Operatori void operator+(int nrPosts); // Supraincarcam operatorul "+" } // user.cpp // La fiecare insumare a obiectului , vom mari numarul de posturi void User::operator+(int nrPosts) { this->nrPosts += nrPosts; // Insumam Numarul de Posturi } // entrypoint.cpp #include "User.h" // Includem Clasa de Utilizatori int main() { User user1("Alin", "alin@gmail.com", "alipassword"); // Apelam Constructor Default (Implicit) user1 + 10; // ADAUGAM 10 POSTURI ASUPRA OBIECTULUI !! user1 + 20; // MAI ADAUGAM INCA 20 DE POSTURI // IN TOTAL -- 30 objectToString(user1); // Afisam Obiectul dintr-o functie global cu eticheta de prieten } NOTA** : IN TUTORIALELE CE URMEAZA , VOM INTELEGE & APROFUNDA SUBIECTUL DE SUPRAINCARCARE !!
-
- arithmetic operator
- object
-
(și 1 alta)
Setat cu taguri:
-
Crăciun fericit și sărbători fericite tuturor!
NEFERPITOU a răspuns la topic lui dRama t i c a în Anunțuri
Craciun si Sarbatori Fericite la toata lumea !!- 37 răspunsuri
-
- 1
-
- crăciun fericit
- merry christmas
-
(și 3 altele)
Setat cu taguri:
-
** Obiective ** Prezentare & Implementare Functii Prieten ; Prezentare & Implementare Clase Prieten . ** Functii Prieten ** Functiile prieten reprezinta un concept strict C++ (nemaiintalnit in celalalte limbaje cu paradigma OOP) , ce ne ajuta la furnizarea accesului la membrii privati unei clase cu care este prieten ("friend") . NOTA ** : Acest lucru reprezinta o abatere de la incapsularea membriilor si trebuie folosit cat mai putin posibil . (In doar anumite contexte favorabile) Pentru ca are acces la membrii clasei , nu inseamna ca este MEMBRU AL CLASEI (Nu pot fi accesati prin obiectul clasei). Ele se declara cu eticheta "friend" , in interiorul clasei cu care e prieten . Implementarea acesteia se face in exterior (Global sau in interiorul clasei din care face parte ) . E important sa cunoastem acest concept pentru supraincarcarea operatorilor pe care o vom face in urmatoarele tutoriale !! Functiile Prieten primesc ca argument referintele obiectelor pentru accesul membriilor . ** Exemplu de Utilizare ** /// User.h // Restu Codului friend void objectToString(User& const user); // ACESTA NU MAI ESTE MEMBRU AL CLASEI (DOAR FUNCTIE GLOBALA) // DAR II DAM ATRIBUT DE FUNCTIE PRIETEN AL CLASEI , CE NE DA OPORTUNITATEA SA FOLOSIM MEMBRII // DESI E NU E MEMBRU , EL TREBUIE DECLARAT (NU IMPLEMENTAT) EXPLICIT IN CLASA UNDE ARE NEVOIE DE ACCES . Functia , nefiind membru al clasei , se implementeaza global (daca nu apartine unei clase) sau in interiorul clasei de unde apartine : // User.cpp /// <summary> /// IN AFARA CLASEI /// </summary> /// /// /// void objectToString(User& const user) // Functie globala (NU E TRECUT "User::objectToString()" sa fie membru al clasei) { // DOAR AFISAM CAMPURILE OBIECTULUI std::cout << "\n{" << "\nID Utilizator : " << user.id << " ,\n" // Acces ID FARA GETTER << "Nume Utilizator : " << user.username << " ,\n" // Acces Username FATA GETTER << "Adresa Mail : " << user.email << " ,\n" // Acces Email FARA GETTER << "Parola Utilizator : " << user.password << " ,\n" // Acces Parola FARA GETTER << "Numar Posturi : " << user.nrPosts << ", \n" // Acces la Nr Posturi FARA GETTER << "STATUS BANAT : " << (user.isBanned ? "ESTE INTERZIS " : "NU ESTE INTERZIS") << " PE LEAGUECS!!, \n }"; /* DACA NU ERA FUNCTIE PRIETEN , NU REUSEAM CA FUNCTIE GLOBALA SA ACCESAM MEMBRII FARA GETTERI !!! */ } Iar apelul , in functia principala , va fi : #include "User.h" int main() { User user1("Alin", "alin@gmail.com", "alipassword"); // Apelam Constructor Default (Implicit) objectToString(user1); // Afisam Obiectul dintr-o functie global cu eticheta de prieten } ** Clase Prieten ** Totodata , prieten poate fi o alta clasa , clasa prieten va avea acces la informatia privata a clasei prin care se urmareste o relatie de prietenie . De exemplu , setam clasa Utilizator sa fie prieten cu clasa de manipulare a sirurilor de caractere "StringHandling" , din cadrul proiectului nostru : Prima data , stabilim relatia de prietenie dintre cele doua clase : // StringLGCS.h class StringLGCS{ // RESTUL DECLARATIILOR /// DECLARAM O CLASA PRIETEN UTILIZATOR (TOATE METODELE DIN CLASA UTILIZATOR AU ACCES LA CELE DIN STRINGLGCS) friend class User; }; Iar apoi , in constructorul cu parametrii al clasei Utilizator , de exemplu , accesam continutul privat al clasei "StringLGCS" : // User.cpp // Constructorul cu parametrii cu putine modificari pentru demonstrare User::User(const char* username, const char* email, const char* password) : id{ s_id++ }, nrPosts{ 0 }, isBanned{ false }, stringHandling {nullptr} { StringLGCS friendObject = StringLGCS(username); // Initializam constructorul cu numele de utilizator // Deoarece este stabilita relatia de prietenie , putem printr-un obiect , sa accesam membrul privat fara getteri !!! StringLGCS::allocAndFetchString(&this->username,friendObject.string); // Accesam membrul privat fara probleme friendObject.setString(email); // Schimbam sirul cu urmatoarea informatie StringLGCS::allocAndFetchString(&this->email ,friendObject.string); // Setam Adresa De Mail friendObject.setString(password); StringLGCS::allocAndFetchString(&this->password,friendObject.string); // Setam Parola /// PE SCURT , NU AM AVUT NEVOIE DE GETTERI SA ACCESEZ CONTINUTUL PRIVAT !! } NOTA 1 * : Vom discuta , in tutorialele urmatoare de POO , importanta relatiilor de prietenie si o implementare mai vasta a acestora !! (LA MOMENTUL LOR) NOTA 2 * : Am uitat sa mentionez , RELATIA DE PRIETENIE NU ESTE MUTUALA !! ATENTIE , DACA CLASA "UTILIZATORI" E PRIETEN CU CLASA "STRINGLGCS" , ASTA NU INSEAMNA CA "STRINGLGCS" E PRIETEN CU "UTILIZATORI" !!!!!
-
Ajută serverul de TS3 cu un vot ZILNIC
NEFERPITOU a răspuns la topic lui .GoSSen. în Ajută cu un vot
20077 -
overloading [Programarea Orientata Pe Obiecte - C++] Supraincarcarea metodelor
NEFERPITOU a postat un topic în Windows
** Obiective ** Prezentarea , limitarile impuse dar si exemplificari (in cod C/C++) pe tema supraincarcarii functiilor/metode (clase) . ** Prezentare Concept ** Supraincarcarea functiilor (in C sau C++ din afara claselor) sau a metodelor reprezinta conceptul prin care putem declara si implementa , doua sau mai multe functii cu acelasi nume . NOTA ** : Metode sunt functii situate in cadrul unei clase (membrii) !! Totusi , exista anumite limitari : ** Conditii de Implinit ** FUNCTIILE SAU METODELE TREBUIE SA DIFERE PRIN NUMARUL SI TIPUL DE DATE AL ARGUMENTELE ASOCIATE ACESTUIA !! NU E DE AJUNS SA SCHIMBAM DOAR TIPUL DE DATE RETURNAT !! De exemplu , putem/nu putem supraincarca : // AMBELE NU SE POT SUPRAINCARCA void showObject(); // AICI ORI UNA ORI ALTA int showObject(); // E OK , SE POT SUPRAINCARCA (DIFERA TIPUL DE DATE DINTRE ELE) void showObject(unsigned A); void<(sau alt tip de date)> showObject(float B); // <> --> E DOAR INFORMATIONAL // NU SE POT SUPRAINCARCA void showObject(unsigned A,unsigned B); void showObject(bool A , unsigned B); // ASA DA void showObject(unsigned A , unsigned B , unsigned C); void showObject(bool A,unsigned B); //// si tot asa .. ** Exemplu de Lucru cu functii/metode ** Adaugim , din proiectul trecut , cinci functii supraincarcate : // user.h --> declarare //// ... class User{ ////.... // Alte Functii // Vizualizare Obiect void objectToString() const; // Afisam Obiectul cum este // Astea doua jos merg supraincarcate deoarece avem argumentul schimbat void objectToString(unsigned nrPosts); // Afisam Obiectul cu Numarul de Posturi schimbat in functie de parametru //int objectToString(unsigned nrPosts); --> ASA NU FUNCTIONEAZA void objectToString(const char* username); // AFISAM CU NUMELE DE UTILIZATOR SCHIMBAT // Astea doua jos merg supraincarcate deoarece avem 1 argument in plus void objectToString(unsigned nrPosts, const char* username,unsigned isBanned); // IDEM SUS + NUMELE DE UTILIZATOR void objectToString(unsigned nrPosts, const char* username); // AFISAM CU STATUS DE BANAT SCHIMBAT SI NUME D EUTILIZATOR }; Le implementam pe fiecare : /// User.cpp ///restu de cod // METODE SUPRAINCARCATE void User::objectToString(unsigned nrPosts) // Metoda 2 (Supraincarcata ) { this->nrPosts = nrPosts; // Setam o valoare preluat din parametru objectToString(); // O apelam pe prima pentru afisare } void User::objectToString(const char* username) { stringHandling->setString(username); // Setam numele intr-un container StringLGCS::allocAndFetchString(&this->username, stringHandling->getString()); // il setam objectToString(); /// afisam obiectul } void User::objectToString(unsigned nrPosts, const char* username, unsigned isBanned) { this->nrPosts = nrPosts; // setam numarul de posturi this->isBanned = isBanned; // setam statusul objectToString(username); // schimbam numele + afisam obiectul } void User::objectToString(unsigned nrPosts, const char* username) { this->nrPosts = nrPosts; // setam numarul de posturi objectToString(username); // schimbam numele + afisam obiectul } Testam codul invocand cele 5 metode supraincarcate : /// entryPoint.cpp #include "User.h" // Includem Clasa de Utilizatori int main() { User user1("Alin", "alin@gmail.com", "alipassword"); // Apelam Constructor Default (Implicit) user1.objectToString(); // AFISAM OBIECTUL CU PARAMETRII DIN CONSTRUCTOR user1.objectToString(12); // AFISAM OBIECTUL + 12 POSTURI user1.objectToString("MARIUS"); // AFISAM OBIECTUL CU NUMELE SCHIMBAT user1.objectToString(25,"VASILE"); // AFISAM OBIECTUL CU NUMELE SCHIMBAT + NUMAR DE POSTURI user1.objectToString(30, "IONEL", true); // AFISAM OBIECTUL CU NUMELE SCHIMBAT + NUMAR DE POSTURI + SCHIMBAT STATUS } REZULTATUL : { ID Utilizator : 0 , Nume Utilizator : Alin , Adresa Mail : alin@gmail.com , Parola Utilizator : alipassword , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 0 , Nume Utilizator : Alin , Adresa Mail : alin@gmail.com , Parola Utilizator : alipassword , Numar Posturi : 12, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 0 , Nume Utilizator : MARIUS , Adresa Mail : alin@gmail.com , Parola Utilizator : alipassword , Numar Posturi : 12, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 0 , Nume Utilizator : VASILE , Adresa Mail : alin@gmail.com , Parola Utilizator : alipassword , Numar Posturi : 25, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 0 , Nume Utilizator : IONEL , Adresa Mail : alin@gmail.com , Parola Utilizator : alipassword , Numar Posturi : 30, STATUS BANAT : ESTE INTERZIS PE LEAGUECS!!, } -
linked list [Structuri de Date - C] Inserare in Liste Inlantuite (Partea 2)
NEFERPITOU a postat un topic în Windows
** Declarare functii de inserare , printare si stergere totala ** // Lists.h #pragma once #include "stdlib.h" // malloc/free #include "string.h" // memcpy typedef struct LinkedList{ // LISTA INLANTUITA GENERICA (O PUTEM FOLOSI CU ORICE TIP DE DATE FARA SA DECLARAM MAI MULTE STRUCTURI) void* Data; // Pastram informatia pentru elementul curent struct LinkedList* nextElement;// Ne corelam cu urmatorul element }Linked_List; void insertAtHead(Linked_List** head, void* data, size_t sizeData); // Inseram de la inceputul listei (Transfer prin adresa , inseram date in lista) void insertAtEnd(Linked_List** head, void* data, size_t sizeData); // Inseram la sfarsitul listei void printLinkedList(Linked_List* head, void(*printDataGeneric)(void*)); // Printam lista void freeLinkedList(Linked_List** head, void(*deleteDataGeneric)(void*)); // Eliberam Lista ** Inserare de la inceput ** Implementam functia de inserare la inceput in "Lists.c" : // Lists.c #include "Lists.h" // Includem Headerul void insertAtHead(Linked_List** head,void* data,size_t sizeData) { // PRIMESTE CA PARAMETRU LISTA PRELUATA PRIN ADRESA (PENTRU MODIFICARI) , INFORMATIA PE CARE O PRIMESTE NODUL SI DIMENSIUNEA ACESTEIA } Inseram date in Nod : // Lists.c #include "Lists.h" // Includem Headerul void insertAtHead(Linked_List** head,void* data,size_t sizeData) { // PRIMESTE CA PARAMETRU LISTA PRELUATA PRIN ADRESA (PENTRU MODIFICARI) , INFORMATIA PE CARE O PRIMESTE NODUL SI DIMENSIUNEA ACESTEIA //// 1. ADAUGAM INFORMATIA CATRE NOD // Alocam un bloc nou de memorie pentru segmentul pe care l introducem Linked_List* newNode = (Linked_List*)malloc(sizeof(Linked_List)); // Inseram date in bloc newNode->Data = malloc(sizeData); // Alocam spatiu pentru informatie memcpy_s(newNode->Data,sizeData,data,sizeData); // Transferam informatia spre blocul nou } Construim legatura cu Urmatorul Nod : // Lists.c #include "Lists.h" // Includem Headerul void insertAtHead(Linked_List** head,void* data,size_t sizeData) { // PRIMESTE CA PARAMETRU LISTA PRELUATA PRIN ADRESA (PENTRU MODIFICARI) , INFORMATIA PE CARE O PRIMESTE NODUL SI DIMENSIUNEA ACESTEIA //// 1. ADAUGAM INFORMATIA CATRE NOD // Alocam un bloc nou de memorie pentru segmentul pe care l introducem Linked_List* newNode = (Linked_List*)malloc(sizeof(Linked_List)); // Inseram date in bloc newNode->Data = malloc(sizeData); // Alocam spatiu pentru informatie memcpy_s(newNode->Data,sizeData,data,sizeData); // Transferam informatia spre blocul nou /// 2. CONSTRUIM LEGATURA CU URMATORUL NOD newNode->nextElement = *head; // URMATORUL NOD VA FI CAPUL CURENT (PRIMUL ELEMENT ) *head = newNode; // NOUL NOD VA FI CAPUL /*** Reprezentare Vizuala : SA presupunem ca dorim sa introducem : 5 , 4 , 2 , 7, 6 (In Lista ) 1. 5 -> NULL 2. 4 -> 5 -> NULL 3. 2 -> 4 -> 5 -> NULL 4. 7 -> 2 -> 4 -> 5 -> NULL 5. 6 -> 7 -> 2 -> 4 -> 5 -> NULL ***/ } ** Inserare de La Capat ** Implementam functia de inserare la sfarsitul listei : // Lists.c void insertAtEnd(Linked_List** head, void* data, size_t sizeData) { // IDEM , DIFERA DOAR MODUL DE FORMARE A LEGATURILOR //// 1. ADAUGAM INFORMATIA CATRE NOD // Alocam un bloc nou de memorie pentru segmentul pe care l introducem Linked_List* newNode = (Linked_List*)malloc(sizeof(Linked_List)); // Inseram date in bloc newNode->Data = malloc(sizeData); // Alocam spatiu pentru informatie memcpy_s(newNode->Data, sizeData, data, sizeData); // Transferam informatia spre blocul nou // INFORMATIA SE ADAUGA LA FEL DOAR DIFERA LEGATURILE newNode->nextElement = NULL; // Setam ca nodul construit sa fie ultimul element // CONTINUARE } Daca lista este goala : if (*head == NULL) // Daca nu avem elemente in lista *head = newNode; // NODUL VA DEVENI CAPUL LISTEI Daca NU : void insertAtEnd(Linked_List** head, void* data, size_t sizeData){ // RESTU CODULUI else { // ALTFEL VOM PARCURGE LISTA PANA LA FINAL Linked_List* lastNode = *head; while (lastNode->nextElement != NULL) // Parcurgem pana la ultimul element lastNode = lastNode->nextElement; // Parcurgem nod cu nod (sau segment) lastNode->nextElement = newNode; // Urmatorul element al ultimului nod va fi cel construit aici } /*** Reprezentare vizuala : 5 , 3 , 2 , 6 , 7 1. 5 -> NULL ; 2 5 -> 3 -> NULL ; 3. 5 -> 3 -> 2 -> NULL; 4. 5 -> 3 -> 2 -> 6 -> NULL; 5. 5 -> 3 -> 2 -> 6 -> 7 -> NULL; ***// } ** Afisare Lista Generica ** Afisarea listei se va efectua generic (adaptata la tipul de date pe care l vom folosi, in cazul nostru Utilizator) : // Lists.c void printLinkedList(Linked_List* head,void(*printDataGeneric)(void*)) { // Preluam lista prin copie dar si o functie pointer care ne permite sa printam un tip de date pe care l dorim (In cazul nostru , Utilizatori) while (head != NULL) // NAVIGAM PANA NU MAI EXISTA ELEMENTE { (*printDataGeneric)(head->Data); // Printam INFORMATIA DIN NOD ADAPTATA LA TIPUL DE DATE PE CARE L VREM NOI head = head->nextElement; // NAVIGAM LA URMATORUL ELEMENT } } ** Stergere Lista Generica ** Stergerea listei se va efectua generic (adaptata la tipul de date pe care l vom folosi , in cazul nostru Utilizator) : void freeLinkedList(Linked_List** head, void(*deleteDataGeneric)(void*)) { // Preluam nodul actual sa l putem sterge Linked_List* nodeToBeDeleted = head; // Stergerea se face de la primul spre ultimul while (*head != NULL) //navigam PANA la capat { nodeToBeDeleted = *head; // Preluam referinta capului *head = (*head)->nextElement; // Mutam capul la urmatorul element //// Stergem informatia din nodul actual (*deleteDataGeneric)(nodeToBeDeleted->Data); // Stergem Generic (Adaptata la tipul nostru de date) free(nodeToBeDeleted->Data); // Stergem blocul de memorie ocupata de informatie free(nodeToBeDeleted); // Stergem nodul in sine } *head = NULL; // SETAM LISTA PE NULL } Testam functiile in programul principal : // entryPoint.c /* Legam toate entry point toate headerele dependente */ #include "../StructuriDate/roles.h" #include "../StructuriDate/fileHandling.h" #include "../StructuriDate/User.h" #include "../StructuriDate//Lists.h" // stringHandling.h nu este dependent de entry point // // CONSTANTELE MACRO SUNT UTILE CA LE PUTEM UTILIZA LA NIVEL GLOBAL (PE TOT FISIERUL) // NOTA** : E O PRACTICA BUNA DE A FOLOSI MACRO SPRE DEOSEBIRE DE CONSTANTE "MAGICE" (NUMERE PRIN COD) #define NR_FILES 2 // STABILIM UN NUMAR DE FISIERE int main() { FILE** file = NULL; file = (FILE**)malloc(sizeof(FILE*)*NR_FILES); // DECLARAM O COLECTIE DE FISIERE file[0] = openFile(FILENAME_INPUT_ROLES, READMODE_TXT); // CITIM ROLURILE DINTR-UN FISIER TEXT file[1] = openFile(FILENAME_USER_INPUT, READMODE_TXT); // CITIM UTILIZATORI DINTR-UN FISIER TEXT // dateIntrareLeagueCS.txt && dateIntrareRoluriLeagueCS.txt TREBUIE SA EXISTE IN DIRECTOR (ALTFEL VA ESUA) Role* roles = fetchRoles(file[0]); // Am primit lista cu rolurile User* users = fetchUsersFromTxtFile(file[1],roles); // Am primit informatia despre utilizatori Linked_List* list = NULL; // Declaram lista nula for (int i = 0; i < 3; i++) // Primii 3 ii inseram de la cap insertAtHead(&list, users + i, sizeof(users[i])); // inseram al doilea element al listei ca cap al listei (1) for (int i = 3; i < 6; i++) // Ceilalti de la coada insertAtEnd(&list, users + i, sizeof(users[i])); // inseram al doilea element al listei ca cap al listei (1) printLinkedList(list, printUser); // ELIBERAM RESURSELE freeLinkedList(&list, freeUser); // Eliberam Nodurile + Lista va fi NULA freeRoles(&roles); // Eliberam resursele ocupate de entitate free(users); // Stergem colectia closeFiles(&file,NR_FILES); // Eliberam resursele ocupate de fisiere if (file == NULL) printf("COLECTIA DE FISIERE A FOST ELIBERATA CU SUCCES !! "); return 0; } Si vom avea rezultatul : **FISIERUL dateIntrareRoluriLeagueCS.txt S-A DESCHIS CU SUCCES !** **FISIERUL dateIntrareUtilizatoriLeagueCS.txt S-A DESCHIS CU SUCCES !** User 0 : { ID UTILIZATOR: 2 , NUME UTILIZATOR: Alivcxvxcn , ADRESA MAIL UTILIZATOR: alidsadvfcn@gmail.com , PAROLA : dsewqqewqadc , NUMAR POSTURI : 550 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 3 | NUME ROL : Super Moderator ID ROL : 1 | NUME ROL : Utilizator Premium } }User 1 : { ID UTILIZATOR: 1 , NUME UTILIZATOR: Alinds , ADRESA MAIL UTILIZATOR: alidasdsan@gmail.com , PAROLA : dsavvcvdc , NUMAR POSTURI : 50 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru ID ROL : 1 | NUME ROL : Utilizator Premium } }User 2 : { ID UTILIZATOR: 0 , NUME UTILIZATOR: Alin , ADRESA MAIL UTILIZATOR: alidsadan@gmail.com , PAROLA : dsdasdadsadadc , NUMAR POSTURI : 100 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru ID ROL : 3 | NUME ROL : Super Moderator ID ROL : 4 | NUME ROL : Administrator ID ROL : 1 | NUME ROL : Utilizator Premium } }User 3 : { ID UTILIZATOR: 3 , NUME UTILIZATOR: Alifdsfn , ADRESA MAIL UTILIZATOR: alewewin@gmail.com , PAROLA : dsfdsfsdfsadc , NUMAR POSTURI : 3300 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru ID ROL : 1 | NUME ROL : Utilizator Premium ID ROL : 2 | NUME ROL : Moderator ID ROL : 3 | NUME ROL : Super Moderator ID ROL : 4 | NUME ROL : Administrator } }User 4 : { ID UTILIZATOR: 4 , NUME UTILIZATOR: Alie2qweqn , ADRESA MAIL UTILIZATOR: alcxsaxcadsain@gmail.com , PAROLA : dsvcvvvvadc , NUMAR POSTURI : 11100 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru } }User 5 : { ID UTILIZATOR: 5 , NUME UTILIZATOR: Alidasdadan , ADRESA MAIL UTILIZATOR: alidasdassdadn@gmail.com , PAROLA : dsvvvvvvvvradc , NUMAR POSTURI : 134300 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru ID ROL : 2 | NUME ROL : Moderator ID ROL : 1 | NUME ROL : Utilizator Premium ID ROL : 3 | NUME ROL : Super Moderator } }COLECTIA DE FISIERE A FOST ELIBERATA CU SUCCES !! OBS 1 ** : PRIMELE 3 SUNT INSERATE (2->1->0) IAR ULTIMELE 3 (3->4->5) (VA ORIENTATI DUPA ID-URI) !! NOTA ** : DACA INTERVIN COMPLICATII , PM ME SAU REPLY !-
- generic list
- void pointer
-
(și 2 altele)
Setat cu taguri:
-
linked list [Structuri de Date - C] Inserare in Liste Inlantuite (Partea 1)
NEFERPITOU a postat un topic în Windows
** Obiective ** Construim o structura de Utilizatori LGCS cu campuri precum : ID , Nume , Adresa de Mail , Parola , NrPosturi , isBanned dar si rolurile din care face parte ; Constituim o lista inlantuita (generica) cu toate componentele acestuia (POINTER DE REFERINTA SI INFORMATIE) Inseram date dintr-un fisier text (pe care l voi pune in atasament) . Completam lista cu toate datele din fisier ; Afisam & Eliberam Toata Lista . NOTA ** : Vom folosi proiectul din tutorialele trecute de Structuri . (Cu Roluri) ** Declarare Structura Utilizatori LGCS ** // User.h typedef struct User { // INFORMATIE UTILIZATOR unsigned id; // ID UTILIZATOR char* username; // NUME UTILIZATOR char* email; // ADRESA MAIL UTILIZATOR char* password; // PAROLA UTILIZATOR unsigned nrPosts; // NUMAR POSTURI unsigned isBanned; // NU AVEM VALOARE BOOLEANA IN C (bool) ==> "1" E TRUE && "0" E FALSE Role* roles; // Colectie de grupuri din care face parte utilizatorul }User; ** Declarare Lista Inlantuita ** // Lists.h ----> FISIER NOU typedef struct Linked_List{ // LISTA INLANTUITA GENERICA (O PUTEM FOLOSI CU ORICE TIP DE DATE FARA SA DECLARAM MAI MULTE STRUCTURI) void* Data; // Pastram informatia pentru elementul curent Linked_List* nextElement; // Ne corelam cu urmatorul element }LinkedList; // Asta reprezinta o eticheta pentru structura ==> Scriem "LinkedList" inloc de "struct Linked_List" NOTA ** : "void*" REPREZINTA un caz particular in C , o modalitatea de a substitui mai multe tipuri de date pentru a EVITA declararea Listei pentru fiecare tip de date . De exemplu , daca doresc ca lista sa fie folosita apoi , pentru structura "studenti" sau "masini" sau altceva , o putem refolosi fara sa facem lista pentru fiecare tip de structura . (tip de date) ** Preluare Utilizator din Fisier ** Declaram o functie pentru incarcarea datelor din fisier in vederea initializarii structuri : // User.h /// Structura & Restu Codului #include "roles.h" // Avem nevoie pentru tipul de date Role #define FILENAME_USER_INPUT "dateIntrareUtilizatoriLeagueCS.txt" // Definim un nume pentru intrare User* fetchUsersFromTxtFile(FILE* inputTxt,Role* roles); // Incarcam o colectie de utilizatori din fisier Ne asiguram ca putem stoca suficient spatiu pentru fiecare linie : // stringHandling.h // Restu Codului #define MAX_STRING_LINE 256 // Alocam maxim 256 de caractere pentru linii Trecem la implementarea codului pentru incarcarea utilizatorului din fisier !! // user.c #include "User.h" // legam cu fisierul asociat acestuia (de unde vin declaratiile) User* fetchUsersFromTxtFile(FILE* inputTxt, Role* roles) // Implementam functia de inserare a datelor { // Implementare } Verificam daca fisierul este eligibil pentru inserare : // user.c User* fetchUsersFromTxtFile(FILE* inputTxt, Role* roles) // Implementam functia de inserare a datelor { if (!checkFile(inputTxt)) return NULL; // Fisier Invalid + Returnam o valoare NULA Colectiei } Daca totul e ok , declaram o colectie de utilizatori dar si un contor pentru indexare : // user.c User* fetchUsersFromTxtFile(FILE* inputTxt, Role* roles) // Implementam functia de inserare a datelor { if (!checkFile(inputTxt)) return NULL; // Fisier Invalid + Returnam o valoare NULA Colectiei unsigned i = 1; // Pentru accesarea elementelor curente va fi (i-1) User* newUser = (User*)malloc(sizeof(User)); // Alocam pentru un utilizator (MOMENTAN) } Adaugam o colectie de caractere , ca intermediar , pentru preluare a linie cu linie din fisier : // user.c User* fetchUsersFromTxtFile(FILE* inputTxt, Role* roles) // Implementam functia de inserare a datelor { if (!checkFile(inputTxt)) return NULL; // Fisier Invalid + Returnam o valoare NULA Colectiei unsigned i = 1; // Pentru accesarea elementelor curente va fi (i-1) User* newUser = (User*)malloc(sizeof(User)); // Alocam pentru un utilizator (MOMENTAN) char bufferLine[MAX_STRING_LINE]; // Cu spatiu alocat explicit mai sus } Citim linie cu linie din fisier cu "fgets" (pana la finalul fisierului) iar continutul (toata linia) o oferim colectiei declarate mai sus : // user.c User* fetchUsersFromTxtFile(FILE* inputTxt, Role* roles) // Implementam functia de inserare a datelor { if (!checkFile(inputTxt)) return NULL; // Fisier Invalid + Returnam o valoare NULA Colectiei unsigned i = 1; // Pentru accesarea elementelor curente va fi (i-1) User* newUser = (User*)malloc(sizeof(User)); // Alocam pentru un utilizator (MOMENTAN) char bufferLine[MAX_STRING_LINE]; // Cu spatiu alocat explicit mai sus while ((fgets(bufferLine, MAX_STRING_LINE, inputTxt)) != NULL) // Citim Linie cu Linie din Fisier { // Implementare } } Citim si inseram in colectia de Utilizatori , informatiile despre ID , NUME , EMAIL , PAROLA , NUMAR POSTURI SI DACA E BANAT : // user.c User* fetchUsersFromTxtFile(FILE* inputTxt, Role* roles) // Implementam functia de inserare a datelor { if (!checkFile(inputTxt)) return NULL; // Fisier Invalid + Returnam o valoare NULA Colectiei unsigned i = 1; // Pentru accesarea elementelor curente va fi (i-1) User* newUser = (User*)malloc(sizeof(User)); // Alocam pentru un utilizator (MOMENTAN) char bufferLine[MAX_STRING_LINE]; // Cu spatiu alocat explicit mai sus while ((fgets(bufferLine, MAX_STRING_LINE, inputTxt)) != NULL) // Citim Linie cu Linie din Fisier { char*Token, *nextToken; // Prima va retine informatia curenta iar cealalta referinta la cea mai ramas din linie // Inseram Date /// ID Token = strtok_s(bufferLine,DELIMITATER,&nextToken); // Preluam ID-ul din linie in format de STRING newUser[i-1].id = atoi(Token); // Convertim din string in intreg + Il Incarcam in Structura // NUME Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam NUMELE din linie in format de STRING allocAndFetchString(&newUser[i-1].username,Token); // Il Incarcam in Structura // Adresa de Mail Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam EMAIL din linie in format de STRING allocAndFetchString(&newUser[i-1].email, Token); // Il Incarcam in Structura // Parola Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam EMAIL din linie in format de STRING allocAndFetchString(&newUser[i-1].password, Token); // Il Incarcam in Structura // NrPosts Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam NUMARUL DE POSTURI DIN STRUCTURA newUser[i-1].nrPosts = atoi(Token); // CONVERTIM DIN STRING IN INTREG SI IL INCARCAM // e Banat Token = strtok_s(NULL, DELIMITATER, &nextToken); // IDEM newUser[i-1].isBanned = atoi(Token); } } Acum , traversam toate rolurile inserate din tutorialul anterior iar apoi le vom asocia cu id-urile rolurilor din care face parte utilizatorul curent : // user.c User* fetchUsersFromTxtFile(FILE* inputTxt, Role* roles) // Implementam functia de inserare a datelor { if (!checkFile(inputTxt)) return NULL; // Fisier Invalid + Returnam o valoare NULA Colectiei unsigned i = 1; // Pentru accesarea elementelor curente va fi (i-1) User* newUser = (User*)malloc(sizeof(User)); // Alocam pentru un utilizator (MOMENTAN) char bufferLine[MAX_STRING_LINE]; // Cu spatiu alocat explicit mai sus while ((fgets(bufferLine, MAX_STRING_LINE, inputTxt)) != NULL) // Citim Linie cu Linie din Fisier { char*Token, *nextToken; // Prima va retine informatia curenta iar cealalta referinta la cea mai ramas din linie // Inseram Date /// ID Token = strtok_s(bufferLine,DELIMITATER,&nextToken); // Preluam ID-ul din linie in format de STRING newUser[i-1].id = atoi(Token); // Convertim din string in intreg + Il Incarcam in Structura // NUME Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam NUMELE din linie in format de STRING allocAndFetchString(&newUser[i-1].username,Token); // Il Incarcam in Structura // Adresa de Mail Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam EMAIL din linie in format de STRING allocAndFetchString(&newUser[i-1].email, Token); // Il Incarcam in Structura // Parola Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam EMAIL din linie in format de STRING allocAndFetchString(&newUser[i-1].password, Token); // Il Incarcam in Structura // NrPosts Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam NUMARUL DE POSTURI DIN STRUCTURA newUser[i-1].nrPosts = atoi(Token); // CONVERTIM DIN STRING IN INTREG SI IL INCARCAM // e Banat Token = strtok_s(NULL, DELIMITATER, &nextToken); // IDEM newUser[i-1].isBanned = atoi(Token); // Grupurile din care face parte unsigned j = 1; // (Accesul la itemul curent se va face la (j-1)) while ((Token = strtok_s(NULL, DELIMITATER, &nextToken)) != NULL) // Preluam ID cu ID { unsigned targetIdRole, k = 0; targetIdRole = atoi(Token); // Convertim ID-ul din string in intreg do { if (targetIdRole == roles[k].id) // DACA AM REGASIT ID-UL IN COLECTIE DE ROLURI { newUser[i-1].roles = j == 1 ? (Role*)malloc(sizeof(Role)) // DACA SUNTEM LA PRIMA ITERATIE : (Role*)realloc(newUser[i-1].roles, sizeof(Role) * j); // DACA SUNTEM LA J ITERATIE // Preluam Referintele (ODATA ELIBERATE ROLURILE SI ELE ISI VOR PIERDE INFORMATIA ) newUser[i-1].roles[j-1].id = roles[k].id; newUser[i-1].roles[j-1].nameRole = roles[k].nameRole; newUser[i-1].roles[j-1].isLastRole = 0; // NU ESTE ULTIMUL ELEMENT DIN LISTA break; // NU ARE ROST SA PARCURGEM TOATA STRUCTURA } k++; // Incrementam cu un pas } while(!roles[k-1].isLastRole); // Parcurgem toate rolurile PANA AJUNGEM LA ULTIMUL j++; // Marim colectia cu un element } newUser[i-1].roles[j-2].isLastRole = 1; // ESTE ULTIMUL ELEMENT DIN LISTA } } Verificam daca mai avem continut in fisier . Daca da , vom realoca un nou utilizatori (in functie de cati utilizatori sunt introdusi in fisier) . Daca nu , se opreste iteratia si se returneaza ce am adaugat : // user.c User* fetchUsersFromTxtFile(FILE* inputTxt, Role* roles) // Implementam functia de inserare a datelor { if (!checkFile(inputTxt)) return NULL; // Fisier Invalid + Returnam o valoare NULA Colectiei unsigned i = 1; // Pentru accesarea elementelor curente va fi (i-1) User* newUser = (User*)malloc(sizeof(User)); // Alocam pentru un utilizator (MOMENTAN) char bufferLine[MAX_STRING_LINE]; // Cu spatiu alocat explicit mai sus while ((fgets(bufferLine, MAX_STRING_LINE, inputTxt)) != NULL) // Citim Linie cu Linie din Fisier { char*Token, *nextToken; // Prima va retine informatia curenta iar cealalta referinta la cea mai ramas din linie // Inseram Date /// ID Token = strtok_s(bufferLine,DELIMITATER,&nextToken); // Preluam ID-ul din linie in format de STRING newUser[i-1].id = atoi(Token); // Convertim din string in intreg + Il Incarcam in Structura // NUME Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam NUMELE din linie in format de STRING allocAndFetchString(&newUser[i-1].username,Token); // Il Incarcam in Structura // Adresa de Mail Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam EMAIL din linie in format de STRING allocAndFetchString(&newUser[i-1].email, Token); // Il Incarcam in Structura // Parola Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam EMAIL din linie in format de STRING allocAndFetchString(&newUser[i-1].password, Token); // Il Incarcam in Structura // NrPosts Token = strtok_s(NULL, DELIMITATER, &nextToken); // Preluam NUMARUL DE POSTURI DIN STRUCTURA newUser[i-1].nrPosts = atoi(Token); // CONVERTIM DIN STRING IN INTREG SI IL INCARCAM // e Banat Token = strtok_s(NULL, DELIMITATER, &nextToken); // IDEM newUser[i-1].isBanned = atoi(Token); // Grupurile din care face parte unsigned j = 1; // (Accesul la itemul curent se va face la (j-1)) while ((Token = strtok_s(NULL, DELIMITATER, &nextToken)) != NULL) // Preluam ID cu ID { unsigned targetIdRole, k = 0; targetIdRole = atoi(Token); // Convertim ID-ul din string in intreg do { if (targetIdRole == roles[k].id) // DACA AM REGASIT ID-UL IN COLECTIE DE ROLURI { newUser[i-1].roles = j == 1 ? (Role*)malloc(sizeof(Role)) // DACA SUNTEM LA PRIMA ITERATIE : (Role*)realloc(newUser[i-1].roles, sizeof(Role) * j); // DACA SUNTEM LA J ITERATIE // Preluam Referintele (ODATA ELIBERATE ROLURILE SI ELE ISI VOR PIERDE INFORMATIA ) newUser[i-1].roles[j-1].id = roles[k].id; newUser[i-1].roles[j-1].nameRole = roles[k].nameRole; newUser[i-1].roles[j-1].isLastRole = 0; // NU ESTE ULTIMUL ELEMENT DIN LISTA break; // NU ARE ROST SA PARCURGEM TOATA STRUCTURA } k++; // Incrementam cu un pas } while(!roles[k-1].isLastRole); // Parcurgem toate rolurile PANA AJUNGEM LA ULTIMUL j++; // Marim colectia cu un element } newUser[i-1].roles[j-2].isLastRole = 1; // ESTE ULTIMUL ELEMENT DIN LISTA if (!feof(inputTxt)) // Daca mai sunt date in fisier newUser = realloc(newUser, sizeof(User) * (++i)); // Mai alocam un utilizator } return newUser; // Returnam colectia } IN TUTORIALUL ACESTA NU VOI INTRODUCE IN LISTE , UTILIZATORI DAR VOM AFISA CONTINUTUL SI LE VOM STERGE (SUB FORMA DE ARRAY) (ASA CA BONUS ) Declaram functiile de afisare si stergere : // User.h // Restu codului void printUser(User user); void freeUser(User user); Le implementam : /// User.c // Restu Codului void printUser(User user) { static unsigned i = 0; // Retinem i pe toate apelurile printf_s("User %d : { \n",i); printf_s("\tID UTILIZATOR: %d ,\n",user.id); printf_s("\tNUME UTILIZATOR: %s ,\n",user.username); printf_s("\tADRESA MAIL UTILIZATOR: %s ,\n",user.email); printf_s("\tPAROLA : %s ,\n",user.password); printf_s("\tNUMAR POSTURI : %d ,\n", user.nrPosts); printf_s("\tESTE BANAT : %s ,\n", user.isBanned ? "DA" : "NU"); printf_s("\t\tROLURI DETINUTE : {\n"); unsigned j = 0; do { printf_s("\n\tID ROL : %d | NUME ROL :%s",user.roles[j].id,user.roles[j].nameRole); j++; } while(!user.roles[j-1].isLastRole); printf_s("\n}\n}"); i++; } void freeUser(User user) { //Stergem sirurile de caractere free(user.username); free(user.email); free(user.password); // ROLURILE VOR FI STERSE SEPARATE in functia freeRoles() } Acum , afisam in functia principala utilizatorii iar pe urma , ii stergem : // entryPoint.c /* Legam toate entry point toate headerele dependente */ #include "../StructuriDate/roles.h" #include "../StructuriDate/fileHandling.h" #include "../StructuriDate/User.h" #include "../StructuriDate//Lists.h" // stringHandling.h nu este dependent de entry point // // CONSTANTELE MACRO SUNT UTILE CA LE PUTEM UTILIZA LA NIVEL GLOBAL (PE TOT FISIERUL) // NOTA** : E O PRACTICA BUNA DE A FOLOSI MACRO SPRE DEOSEBIRE DE CONSTANTE "MAGICE" (NUMERE PRIN COD) #define NR_FILES 2 // STABILIM UN NUMAR DE FISIERE int main() { FILE** file = NULL; file = (FILE**)malloc(sizeof(FILE*)*NR_FILES); // DECLARAM O COLECTIE DE FISIERE file[0] = openFile(FILENAME_INPUT_ROLES, READMODE_TXT); // CITIM ROLURILE DINTR-UN FISIER TEXT file[1] = openFile(FILENAME_USER_INPUT, READMODE_TXT); // CITIM UTILIZATORI DINTR-UN FISIER TEXT // dateIntrareLeagueCS.txt && dateIntrareRoluriLeagueCS.txt TREBUIE SA EXISTE IN DIRECTOR (ALTFEL VA ESUA) Role* roles = fetchRoles(file[0]); // Am primit lista cu rolurile User* users = fetchUsersFromTxtFile(file[1],roles); // Am primit informatia despre utilizatori for (int i = 0; i < 6; i++) { // CUNOASTEM CA SUNT SASE ENTITATI printUser(users[i]); // Accesul prin index (Array) --> AFISAM UTILIZATORUL CURENT freeUser(users[i]); // STERGEM UTILIZATORUL CURENT } // ELIBERAM RESURSELE freeRoles(&roles); // Eliberam resursele ocupate de entitate free(users); // Stergem colectia closeFiles(&file,NR_FILES); // Eliberam resursele ocupate de fisiere if (file == NULL) printf("COLECTIA DE FISIERE A FOST ELIBERATA CU SUCCES !! "); return 0; } Si primim ca output : **FISIERUL dateIntrareRoluriLeagueCS.txt S-A DESCHIS CU SUCCES !** **FISIERUL dateIntrareUtilizatoriLeagueCS.txt S-A DESCHIS CU SUCCES !** User 0 : { ID UTILIZATOR: 0 , NUME UTILIZATOR: Alin , ADRESA MAIL UTILIZATOR: alidsadan@gmail.com , PAROLA : dsdasdadsadadc , NUMAR POSTURI : 100 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru ID ROL : 3 | NUME ROL : Super Moderator ID ROL : 4 | NUME ROL : Administrator ID ROL : 1 | NUME ROL : Utilizator Premium } }User 1 : { ID UTILIZATOR: 1 , NUME UTILIZATOR: Alinds , ADRESA MAIL UTILIZATOR: alidasdsan@gmail.com , PAROLA : dsavvcvdc , NUMAR POSTURI : 50 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru ID ROL : 1 | NUME ROL : Utilizator Premium } }User 2 : { ID UTILIZATOR: 2 , NUME UTILIZATOR: Alivcxvxcn , ADRESA MAIL UTILIZATOR: alidsadvfcn@gmail.com , PAROLA : dsewqqewqadc , NUMAR POSTURI : 550 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 3 | NUME ROL : Super Moderator ID ROL : 1 | NUME ROL : Utilizator Premium } }User 3 : { ID UTILIZATOR: 3 , NUME UTILIZATOR: Alifdsfn , ADRESA MAIL UTILIZATOR: alewewin@gmail.com , PAROLA : dsfdsfsdfsadc , NUMAR POSTURI : 3300 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru ID ROL : 1 | NUME ROL : Utilizator Premium ID ROL : 2 | NUME ROL : Moderator ID ROL : 3 | NUME ROL : Super Moderator ID ROL : 4 | NUME ROL : Administrator } }User 4 : { ID UTILIZATOR: 4 , NUME UTILIZATOR: Alie2qweqn , ADRESA MAIL UTILIZATOR: alcxsaxcadsain@gmail.com , PAROLA : dsvcvvvvadc , NUMAR POSTURI : 11100 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru } }User 5 : { ID UTILIZATOR: 5 , NUME UTILIZATOR: Alidasdadan , ADRESA MAIL UTILIZATOR: alidasdassdadn@gmail.com , PAROLA : dsvvvvvvvvradc , NUMAR POSTURI : 134300 , ESTE BANAT : NU , ROLURI DETINUTE : { ID ROL : 0 | NUME ROL : Membru ID ROL : 2 | NUME ROL : Moderator ID ROL : 1 | NUME ROL : Utilizator Premium ID ROL : 3 | NUME ROL : Super Moderator } }COLECTIA DE FISIERE A FOST ELIBERATA CU SUCCES !! NOTA ** : PENTRU A FUNCTIONA ALGORITMUL , SE POT ADAUGA UTILIZATORI LA DISCRETIA VOASTRA DOAR SA PASTREZE MODELUL : id | nume | email | parola | nrPosturi | banat(1/0) | (AICI SE ADAUGA ID-URILE ROLURILOR DIN CARE FACE PARTE DESPARTITE DE "|") ==> LINIE .... .... ... AVETI SABLONUL IN ATASAMENT dateIntrareUtilizatoriLeagueCS.txt-
- file handling
- c
-
(și 3 altele)
Setat cu taguri:
-
linked list [Structuri de Date - C] Introducere in Liste Inlantuite
NEFERPITOU a postat un topic în Windows
** Obiectiv ** Prezentare Generala A Listelor (ca structura de date) ; Afisare , printr-o diagrama , conexiunea dintre elementele listei ; Prezentare Avantaje si Dezavantaje spre deosebire de tablourile de dimensiune (arrays) . ** Listele ** Listele Inlantuite sunt structuri de date complexe , care pot inregistra , citi , modifica sau sterge anumite informatii , pe mai multe segmente(elemente) , referitor la un obiect . De exemplu , pe o lista putem stoca informatii pentru fiecare utilizator al structurii create . Mai mult , FIECARE SEGMENT ESTE LEGAT DE VECINII LUI (In functie de tipul de lista) . De regula , fiecare segment este alcatuit din doua lucruri : INFORMATIE (De exemplu , numele de utilizator , adresa de mail , parole , id etc.) POINTERUL CU REFERINTA SPRE URMATORUL ELEMENT (ELEMENTUL DE LEGATURA CU URMATORUL) ** Avantaje && Dezavantaje ** Pare a fi o structura similara cu tablourile de dimensiune (arrays) dar exista DIFERENTE : Din punct de vedere al memoriei alocate , pentru fiecare element al listei se cere o alocare atat elementului in sine cat si informatiei stocate (daca avem siruri de caractere sau colectii) spre deosebire de "arrays" , unde alocam doar tabloul in sine . (in functie de numarul de elemente * la spatiul ocupat de fiecare element) . Pe de alta parte , in liste alocam DOAR ELEMENTELE pe care le folosim spre deosebire de tablouri , unde trebuie sa aloci toate elementele , INDIFERENT DACA LE FOLOSESTI SAU NU !! . Din punct de vedere al operatiunilor de stergere & inserare , listele prezinta o eficacitate detasata . Din punct de vedere al accesul elementelor , "arrays-urile" ne permit accesul aleatoriu la un element spre deosebire de liste , unde trebuie sa parcurgem element cu element . (secvential ) PE SCURT , RECOMAND SA FOLOSIM LISTE CAND NU DORIM SA RISIPIM MEMORIE SI DORIM SA MANIPULAM DATE (INSERTII , STERGERI , MODIFICARI) . Pe de alta parte , daca dorim sa accesam mai repede anumite elemente , alegem tablourile . NOTA ** : In tutorialul urmator , vom incepe sa efectuam operatiuni cu liste inlantuite !! -
** OBIECTIV ** Prin aceasta postare , dorim sa explicam si sa implementam , folosind codul de POO , conceptul de COPIERE(CLONARE) SUPERFICIALA (aka "Shallow Copy") a unui obiect !! ** Clonarea Unui Obiect ** CLONAREA/COPIEREA UNUI OBIECT reprezinta procedeul de COPIERE a informatiei (membrii clasei) dintr-un obiect (instanta) EXISTENT intr-un obiect NOU (REPLICA) . Acum , ne intrebam de ce sa clonam un obiect , in ce circumstante avem nevoie de acest concept , cu ce ne ajuta ? Pe scurt , ne sprijina prin comoditate . Ne furnizeaza o copie a unui obiect fara sa afectam obiectul original ("COPII DEFENSIVE") . Clonarea unui Obiect se poate efectua , valabil in toate limbajele de programare POO (Java,Python,JavaScript,C# etc.) , sub forma de copie : "Superficiala" sau "Shallow Copy" , se initiaza membrii clasei din obiectul clona , cu REFERINTELE din obiectul original . Pe scurt , orice modificare care survine asupra obiectului clona , VA AFECTA si OBIECTUL ORIGINAL !! (SUNT DEPENDENTE UNA DE CEALALTA) "Adanca" sau "Deep Copy" , se initiaza membrii clasei din obiectul clona , cu VALORILE din obiectul original FARA SA FIE DEPENDENTE UNA DE CEALALTA . Pe scurt , orice modificare a obiectului clona , NU VA AFECTA OBIECTUL ORIGINAL !! (SUNT INDEPENDENTE UNA DE CEALALTA) ** Constructor de Copiere ** Constructorul de copiere reprezinta al treilea tip de constructori , pe langa cel cu parametrii si implicit , si modalitatea de construire a clonelor . Aici se initializeaza membrii obiectului clona cu referintele/valorile membriilor clasei . // CONSTRUCTOR DE COPIERE -- FORMAT constructor_copiere(const NUME_CLASA& obiect_original) // Primim ca parametru , REFERINTA OBIECTULUI ORIGINAL { // AICI SE EFECTUEAZA CLONAREA OBIECTULUI ORIGINAL } NOTA** : DE ASEMENEA , IN CONSTRUCTORUL DE COPIERE PUTEM FOLOSI LISTA DE INITIALIZARE A MEMBRIILOR !!! ** IMPLEMENTARE CLONA SUPERFICIALA ** Adaugam un constructor de copiere , in cadrul clasei "Utilizator" : // user.h class User{ /// RESTU CODULUI User(const User& otherUser); // PREIA REFERINTA OBIECTULUI ORIGINAL (DECLARARE CONSTRUCTOR DE COPIERE) }; + Implementare : // User.cpp User::User(const User& originalObject) // CONSTRUCTOR DE COPIERE (COPIERE SUPERFICIALA ) : id{ originalObject.id }, nrPosts{ originalObject.nrPosts }, isBanned{originalObject.isBanned}, username{ originalObject.username }, email{ originalObject.email }, password{originalObject.password}, stringHandling{originalObject.stringHandling} { //**** OBIECTE ISI IMPART REFERINTELE (POINTERI ISI IMPART REFERINTELE) /* OBIECT ORIGINAL OBIECT CLONA username 0xda34133 --> username 0xda34133 (ISI IMPART ACEEASI ZONA DE MEMORIE) "IONEL" "IONEL" (AUTOMAT , ACEEEASI VALOARE) ==> DACA NUMELE DE UTILIZATOR(EMAIL,STRINGHANDLER,PASSWORD) SE SCHIMBA IN OBIECTUL CLONA , ATUNCI VOR APAREA MODIFICARI SI IN CEL ORIGINAL */ } In programul principal , vom initializa patru obiecte cu tipuri diferite de constructori (cu parametrii , implicit si 2 de copiere) si le vom afisa : // entrypoint.cpp #include "User.h" // Includem Clasa de Utilizatori int main() { User *user3, *user4; { User user1, user2("Vasile", "vasile@gmail.com", "vasileparola"); // Declaram doua instante (una cu constructoru implicit + constructor cu parametrii ) user1.setUsername("IONEL"); // PRODUCEM 2 CLONE user3 = new User(user1); // Clonam Obiectul 1 user4 = new User(user2); // Clonam Obiectul 2 // VIZUALIZAM OBIECTELE ATUNCI CAND OBIECTELE ORIGINALE SUNT IN CONTEXT user1.objectToString(); user2.objectToString(); std::cout << " AFISAM CLONE IN INTERIOURUL CONTEXTULUI : \n"; user3->objectToString(); // Clona Utilizatorului 1 user4->objectToString(); // Clona Utilizatorului 2 std::cout << std::endl; // DINSTANTIEM CU O LINIE CELE DOUA VIZUALIZARI } // AFISAM CLONELE ATUNCI CAND OBIECTELE ORIGINALE AU IESIT DIN CONTEXT (S-A APELAT DESTRUCTORUL) std::cout << " AFISAM CLONE IN AFARA CONTEXTULUI (CAND OBIECTUL ORIGINAL A IESIT DIN CONTEXT) : \n"; user3->objectToString(); // Clona Utilizatorului 1 user4->objectToString(); // Clona Utilizatorului 2 return 0; } Si primim ca rezultat : { ID Utilizator : 0 , Nume Utilizator : IONEL , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 1 , Nume Utilizator : Vasile , Adresa Mail : vasile@gmail.com , Parola Utilizator : vasileparola , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } AFISAM CLONE IN INTERIOURUL CONTEXTULUI : { ID Utilizator : 0 , Nume Utilizator : IONEL , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 1 , Nume Utilizator : Vasile , Adresa Mail : vasile@gmail.com , Parola Utilizator : vasileparola , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } AFISAM CLONE IN AFARA CONTEXTULUI (CAND OBIECTUL ORIGINAL A IESIT DIN CONTEXT) : { ID Utilizator : 0 , Nume Utilizator : ŢŢŢŢŢŢŢŢŢŢ , // ZONA INVALIDA DE MEMORIE Adresa Mail : ŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢ , // ZONA INVALIDA DE MEMORIE Parola Utilizator : ŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢ , // ZONA INVALIDA DE MEMORIE Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 1 , Nume Utilizator : ŢŢŢŢŢŢŢŢŢŢŢ , // ZONA INVALIDA DE MEMORIE Adresa Mail : ŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢ , // ZONA INVALIDA DE MEMORIE Parola Utilizator : ŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢŢ , // ZONA INVALIDA DE MEMORIE Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } NOTA* : TOTUSI , EXISTA O PROBLEMA CU ACEST PROCEDEU DE CONSTRUCTIE A CLONEI . De ce ? Daca se impart aceleasi zone de memorie , riscam sa accesam adrese invalide , astfel daca apelam destructorul pentru obiectele clone : // entryPoint.cpp int main() { // Restu Codului delete user3, user4; // AICI VOM PRIMI EROARE PENTRU CA ELIBERAM ZONE INEXISTENTE DE MEMORIE } DIN ACEASTA CAUZA , SE PREFERA CELALALT TIP DE CONSTRUCTIE , PE CARE L VOM DISCUTA IN TUTORIALUL URMATOR !!
-
** OBIECTIV ** Prin aceasta postare , dorim sa explicam si sa implementam , folosind codul de POO , conceptul de COPIERE(CLONARE) ADANCITA (aka "Deep Copy") a unui obiect !! Clonarea , din aceasta perspectiva , se va efectua FARA a creea dependente intre obiecte . In sensul ca , va prelua valorile din obiectele originale DAR se vor construi NOI zone de memorie !!! ** IMPLEMENTARE CLONA ADANCITA ** Adaugam un constructor de copiere , in cadrul clasei "Utilizator" (SIMILAR CU CEL SUPERFICIAL , LA DECLARATIE) : // user.h class User{ /// RESTU CODULUI User(const User& otherUser); // PREIA REFERINTA OBIECTULUI ORIGINAL (DECLARARE CONSTRUCTOR DE COPIERE) }; + Implementare : // User.cpp User::User(const User& originalObject) // CONSTRUCTOR DE COPIERE (COPIERE ADANCITA) : id{ originalObject.id }, nrPosts{ originalObject.nrPosts }, isBanned{originalObject.isBanned}, stringHandling{new StringLGCS(originalObject.username)} { //**** POINTERI ISI IMPART VALORILE , NU REFERINTELE /* OBIECT ORIGINAL OBIECT CLONA username 0xda34133 --> username 0xdc999 (ZONE SEPARATE DE MEMORIE ) "IONEL" "IONEL" (VALORI SIMILARE) */ StringLGCS::allocAndFetchString(&this->username, stringHandling->getString()); // Setam Numele de Utilizator stringHandling->setString(originalObject.email); // Schimbam sirul cu urmatoarea informatie StringLGCS::allocAndFetchString(&this->email, stringHandling->getString()); // Setam Adresa De Mail stringHandling->setString(originalObject.password); StringLGCS::allocAndFetchString(&this->password, stringHandling->getString()); // Setam Parola } In programul principal , vom initializa patru obiecte cu tipuri diferite de constructori (cu parametrii , implicit si 2 de copiere) si le vom afisa : // entryPoint.cpp #include "User.h" // Includem Clasa de Utilizatori int main() { User *user3, *user4; { User user1, user2("Vasile", "vasile@gmail.com", "vasileparola"); // Declaram doua instante (una cu constructoru implicit + constructor cu parametrii ) user1.setUsername("IONEL"); // PRODUCEM 2 CLONE user3 = new User(user1); // Clonam Obiectul 1 user4 = new User(user2); // Clonam Obiectul 2 // VIZUALIZAM OBIECTELE ATUNCI CAND OBIECTELE ORIGINALE SUNT IN CONTEXT user1.objectToString(); user2.objectToString(); std::cout << " AFISAM CLONE IN INTERIOURUL CONTEXTULUI : \n"; user3->objectToString(); // Clona Utilizatorului 1 user4->objectToString(); // Clona Utilizatorului 2 std::cout << std::endl; // DINSTANTIEM CU O LINIE CELE DOUA VIZUALIZARI } // AFISAM CLONELE ATUNCI CAND OBIECTELE ORIGINALE AU IESIT DIN CONTEXT (S-A APELAT DESTRUCTORUL) std::cout << " AFISAM CLONE IN AFARA CONTEXTULUI (CAND OBIECTUL ORIGINAL A IESIT DIN CONTEXT) : \n"; user3->objectToString(); // Clona Utilizatorului 1 user4->objectToString(); // Clona Utilizatorului 2 delete user3, user4; // TOTUL ESTE OK , SUNT ZONE SEPARATE DE MEMORIE return 0; } Si primim ca rezultat : { ID Utilizator : 0 , Nume Utilizator : IONEL , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 1 , Nume Utilizator : Vasile , Adresa Mail : vasile@gmail.com , Parola Utilizator : vasileparola , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } AFISAM CLONE IN INTERIOURUL CONTEXTULUI : { ID Utilizator : 0 , Nume Utilizator : IONEL , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 1 , Nume Utilizator : Vasile , Adresa Mail : vasile@gmail.com , Parola Utilizator : vasileparola , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } AFISAM CLONE IN AFARA CONTEXTULUI (CAND OBIECTUL ORIGINAL A IESIT DIN CONTEXT) : { ID Utilizator : 0 , Nume Utilizator : IONEL , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 1 , Nume Utilizator : Vasile , Adresa Mail : vasile@gmail.com , Parola Utilizator : vasileparola , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } NOTA * : IN CONCLUZIE , in aceasta abordare , spre deosebire de cealalta ("superficiala") , sunt construite zone de memorie NOI (DOAR VALOAREA ESTE PRELUATA DIN OBIECTELE ORIGINALE) ASTFEL DEVENIND OBIECTE INDEPENDENTE UNA DE CEALALTA , IN CIUDA CA SI IMPART ACELEASI VALORI !! TOTODATA , VOI RECOMANDA ACEASTA MODALITATE PENTRU EVITAREA ERORILOR !!
-
constructor [Programarea Orientata Pe Obiecte - C++] Initializare Lista Constructor Membri
NEFERPITOU a răspuns la topic lui NEFERPITOU în Windows
Multumesc pentru feedback si sutinere . Pe zi ce trece , imi dau silinta sa aduc tutoriale la standarde cat mai bune dar si interpretabile pentru persoanele care sunt la inceput sau progreseaza . Toate bune !- 2 răspunsuri
-
- lista constructor membrii
- constante
-
(și 2 altele)
Setat cu taguri:
-
** Obiectiv ** In tutorialul acesta , vom prezenta o alternativa , mult mai corecta , pentru initializarea membriilor unei clase , in semnatura constructorului . NOTA ** : Codul va fi preluat din proiectul de la tutorialele trecute de POO . (Cu mici modificari evidentiate ) ** Model ** constructor(x,y,z,...,c) : m_x{x},m_y{y},m_z{z},......,m_c{c} { // Continut Constructor } // m_x --> membru al clasei && x = parametru(variabila cu stocare locala) ** Initializarea variabilelor & Pointerilor ** // User.cpp //** Implementarea Constructorilor **// User::User() : id{ 0 }, nrPosts{ 0 }, isBanned{ false } , stringHandling{ new StringLGCS()} // Lista Constructor Membrii de Initializat { // Constructor Fara Parametrii // Alocam si Initializam date cu informatii IMPLICITE (DEFAULT ) /// FUNCTIILE STATICE SE INVOCA FOLOSIND "::" !!! StringLGCS::allocAndFetchString(&this->username, stringHandling->getString()); StringLGCS::allocAndFetchString(&this->email, stringHandling->getString()); StringLGCS::allocAndFetchString(&this->password, stringHandling->getString()); } // Idem User::User(unsigned id, const char* username, const char* email, const char* password) : id{ id }, nrPosts{ 0 }, isBanned{ false },stringHandling{new StringLGCS(username)} // IDEM { StringLGCS::allocAndFetchString(&this->username, stringHandling->getString()); // Setam Numele de Utilizator stringHandling->setString(email); // Schimbam sirul cu urmatoarea informatie StringLGCS::allocAndFetchString(&this->email , stringHandling->getString()); // Setam Adresa De Mail stringHandling->setString(password); StringLGCS::allocAndFetchString(&this->password, stringHandling->getString()); // Setam Parola } NOTA 1 ** : ACEASTA ABORDARE SE APLICA DOAR CONSTRUCTORILOR , IN SEMNATURA ACESTORA ; NOTA 2** : IN CADRUL ACESTEIA , NU ESTE NECESAR DIFERENTIEREA DINTRE MEMBRII CLASEI (Declaratia din AFARA ACOLADEI) SI CEI LOCALI (Partea din ACOLADA) NOTA 3** : PUTEM APELA , DE ASEMENEA , FUNCTII IN INTERIORUL ACOLODELOR , CONDITIA E SA RETURNEZE TIPUL DE DATE CORESPONDENT MEMBRULUI . ** Initializare Constante & Valori Statice ** O utilitate foarte importanta a acestei forme de initializare , e faptul ca ne permite sa initializam CONSTANTE !!! Pe aceasta cale , ii vom atribui id-ului fiecarui utilizator , o valoare constanta si incrementat la fiecare instantiere printr-o variabila statica . // user.h class User{ const unsigned id; // COD UNIC DE IDENTIFICARE UTILIZATOR CONSTANT --> II APLICAM ID-UL UN ATRIBUT CONSTANT (EL NU SE SCHIMBA) static inline unsigned s_id; // VALOARE STATICA INTERMEDIARA --> ADAUGAM O VALOARE STATICA PENTRU A RETINE NUMARUL DE INSTANTIERI User(const char* username, const char* email, const char* password); // --> MODIFICAM CONSTRUCTORUL , NU AVEM NEVOIE DE PARAMETRUL ID !! // Restul de declaratii }; Noua Implementare a constructorilor : /// user.cpp //** Implementarea Constructorilor **// User::User() : id{s_id++}, nrPosts{ 0 }, isBanned{ false }, // lui id ii se atribuie valoarea lui s_id iar apoi s_id se incrementeaza cu o unitate stringHandling{ new StringLGCS()} // Lista Constructor Membrii de Initializat { // Constructor Fara Parametrii // Alocam si Initializam date cu informatii IMPLICITE (DEFAULT ) /// FUNCTIILE STATICE SE INVOCA FOLOSIND "::" !!! StringLGCS::allocAndFetchString(&this->username, stringHandling->getString()); StringLGCS::allocAndFetchString(&this->email, stringHandling->getString()); StringLGCS::allocAndFetchString(&this->password, stringHandling->getString()); } // Idem User::User(const char* username, const char* email, const char* password) : id{s_id++}, nrPosts{ 0 }, isBanned{ false }, stringHandling{new StringLGCS(username)} // IDEM { StringLGCS::allocAndFetchString(&this->username, stringHandling->getString()); // Setam Numele de Utilizator stringHandling->setString(email); // Schimbam sirul cu urmatoarea informatie StringLGCS::allocAndFetchString(&this->email , stringHandling->getString()); // Setam Adresa De Mail stringHandling->setString(password); StringLGCS::allocAndFetchString(&this->password, stringHandling->getString()); // Setam Parola } Revenim la functia principala , instantiem 5 obiecte de tip Utilizator si le afisam : #include "User.h" // Includem Clasa de Utilizatori int main() { User user1, user2("Vasile", "vasile@gmail.com", "vasileparola"), user3, user4, user5; // Declaram doua instante (una cu constructoru implicit + constructor cu parametrii ) // Vizualizam Instantele user1.setUsername("IONEL"); user5.setEmail("psadad@gmail.com"); user4.setPassword("psadxc"); user1.objectToString(); // Vizualizam Instanta 1 user2.objectToString(); // Vizualizam Instanta 2 user3.objectToString(); // Vizualizam Instanta 3 user4.objectToString(); // Vizualizam Instanta 4 user5.objectToString(); // Vizualizam Instanta 5 return 0; } Afisand Obiecte , vom avea urmatorul rezultat : { ID Utilizator : 0 , Nume Utilizator : IONEL , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 1 , Nume Utilizator : Vasile , Adresa Mail : vasile@gmail.com , Parola Utilizator : vasileparola , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 2 , Nume Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 3 , Nume Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Adresa Mail : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Parola Utilizator : psadxc , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } { ID Utilizator : 4 , Nume Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Adresa Mail : psadad@gmail.com , Parola Utilizator : BINE AI VENIT PE COMUNITATEA LEAGUECS!!! , Numar Posturi : 0, STATUS BANAT : NU ESTE INTERZIS PE LEAGUECS!!, } CONCLUZIE : PENTRU FIECARA INSTANTA , NI SE GENEREAZA UN COD UNIC DIFERIT , IN FUNCTIE DE ORDINEA INITIALIZARII !!!
- 2 răspunsuri
-
- lista constructor membrii
- constante
-
(și 2 altele)
Setat cu taguri: