Chirurgia cranio-cerebrală minim invazivă
Tehnicile minim invazive impun utilizarea unei tehnologii ultramoderne. Endoscoapele operatorii de diverse tipuri, microscopul operator dedicat, neuronavigația, neuroelectrofiziologia, tehnicile avansate de anestezie, chirurgia cu pacientul treaz reprezintă armamentarium fără de care neurochirurgia prin "gaura cheii" nu ar fi posibilă. Folosind tehnicile de mai sus, tratăm un spectru larg de patologii cranio-cerebrale. www.neurohope.ro |
De la C la C++
Last Updated: Jul 18 2013 10:21, Started by
dani.user
, Jun 16 2013 17:46
·
0
#19
Posted 12 July 2013 - 22:16
TS030, on 12 iulie 2013 - 21:53, said:
Observ ca mentionezi programarea orientata obiect, dar nu povestesti despre ea si nu exemplifici Ideea a fost de a le starni curiozitatea celor care n-au auzit inca de POO, sa inceapa sa citeasca despre ea, iar, pe masura ce vad cum stau lucrurile, de a exersa cu ajutorul unor studii de caz. Adica ei sa vina cu o problema concreta, intalnita de ei si cu solutia POO la care s-au gandit, iar noi sa o imbunatatim. N-a prea mers insa (inca) ideea, fiindca, in afara de ce am prezentat eu mai sus, nu s-a aratat nimeni interesat. TS030, on 12 iulie 2013 - 21:53, said:
De asemenea, incerci sa vorbesti despre prea multe lucruri deodata, iar structura are de suferit. Am observat si eu ca, in acest caz, am obtinut o structura destul de haotica. Sper s-o rafinez pe parcurs. |
#20
Posted 13 July 2013 - 00:04
Sincer mi se pare ca subiectul abordat abia ar putea fi prins intr-o carte... din fericire, aceasta a fost scrisa deja.
Referitor la OOP, problema e ca nici n-ai inceput sa atingi subiectul, ceea ce poate pacali un incepator. "Componente care rezolva o anumita problema" pot fi si proceduri sau module; desigur, programarea procedurala nu este programare orientata obiect. Nici daca acele componente sunt clase C++ nu poti spune ca programezi neaparat orientat obiect. Exemplul cu HTTPDownloader, ExchangeRateParser, FileWriter care fiecare-si face treaba nu spune nimic despre OOP. Pana nu vorbim de ierarhii de clase, nu vorbim despre OOP. |
#21
Posted 13 July 2013 - 13:04
Am mentionat si ierarhii de clase, exemplul cu Persoana/Elev.
|
#22
Posted 14 July 2013 - 11:22
Fix în perioada aceasta m-am apucat de tranziția propriu-zisă, de la C la C++ (mai specific, POO), așa că am încercat să rezolv ”Tema” propusă de dani.user.
String.h #pragma once #include <cstring> namespace Mylib { class String { char* text; public: String(); String(const char* data); int length(); char* subString(int i); //String subString(int i); char* toCharPointer(); String& operator=(const char* data); String& operator=(String& strdata); String operator+(String& strdata); char operator[](int i); String& operator+=(const char* data); String& operator+=(String& strdata); ~String(); }; } String.cpp #include <cstring> #include "String.h" using namespace Mylib; String::String() { text = new char[1]; text[0] = '\0'; } String::String(const char* data) { text = new char[strlen(data) + 1]; strcpy(text,data); } int String::length() { return strlen(text); } char* String::subString(int i) { if (i >= 0 && this->length() >= i) return text + i; } /*String String::subString(int i) { if (i >= 0 && this->length() >= i) { char* buffer = new char[strlen(text+i) + 1]; strcpy(buffer,text+i); String ret(buffer); delete[]buffer; return ret; } }*/ char* String::toCharPointer() { return text; } String& String::operator=(const char* data) { delete[]text; text = new char[strlen(data) + 1]; strcpy(text,data); return *this; } String& String::operator=(String& strdata) { if (this != &strdata) { delete[]text; text = new char[strlen(strdata.text) + 1]; strcpy(text,strdata.text); return *this; } } String String::operator+(String& strdata) { int size = strlen(text) + strdata.length() + 1; char* buffer = new char[size]; buffer = strcpy(buffer,text); buffer = strcat(buffer,strdata.text); String ret(buffer); delete[]buffer; return ret; } char String::operator[](int i) { if (i >= 0 && this->length() >= i); return text[i]; } String& String::operator+=(const char* data) { int size = strlen(text) + strlen(data) + 1; char* buffer = new char[strlen(text) + 1]; buffer = strcpy(buffer,text); delete[]text; text = new char[size]; text = strcpy(text,buffer); delete[]buffer; text = strcat(text,data); return *this; } String& String::operator+=(String& strdata) { int size = strlen(text) + strlen(strdata.text) + 1; char* buffer = new char[strlen(text) + 1]; buffer = strcpy(buffer,text); delete[]text; text = new char[size]; text = strcpy(text,buffer); delete[]buffer; text = strcat(text,strdata.text); return *this; } String::~String() { delete[] text; } test.cpp #include <stdio.h> #include "String.h" using namespace Mylib; int main() { String a; a = "Hello "; int sizeA = a.length(); String b("World"); String c = a + b; //Hello World c += " din C++"; c += a; String d = c.subString(3); //lo World din C++Hello printf("%s\n",d.toCharPointer()); printf("%c",c[0]); // H return 0; } Pentru că sunt încă pe la început de tot și pentru că doresc să învăț, aș aprecia dacă mi-ați oferi feedback și observații: unde mai e de lucrat, ce deprinderi greșite se observă, ce nu e deloc bine ș.a. Aș avea câteva întrebări cu privire la supraîncărcarea operatorilor: 1. De ce se practică transmiterea argumentelor prin const &? const pare cam de amorul artei, dar de ce este necesară adresa obiectului, având în vedere că și în cazul în care operatorul supraîncărcat este cel de atribuire, în cazul a = b, nu ne interesează b decât la nivel de valoare, deci putem opera cu o copie de-a lui b. 2. De ce este nevoie ca atunci când supraîncărcăm ”=”, rezultatul funcției să fie o referință? String& String::operator=(const char* data) { ... return *this; } O altă chestie pe care am observat-o este că funcțiile ce întorc o referință la un obiect prezintă în instr. return obiectul/ valoarea. Mi se pare normal ca în cazul a = b, rezultatul să fie un String, ca atare întorc *this, adică un obiect. Cu toate astea, funcția are ca rezultat String&. Cum de nu există un conflict între tipul funcției și tipul returnat? De asemenea, am întâmpinat ceva probleme când am încercat să implementez funcția subString astfel încât să returneze un obiect de tip String (liniile de cod comentate). Dacă înlocuim funcția char* subString cu cea String subString, o să apară memory map-ul, se pare că problema ar fi un double free/ corruption. Am încercat să fac debug cu gdb-ul, însă nu m-am prins de la ce ar putea fi problema: se pare că ar crăpa cam pe la finalul execuției, când s-ar apela destructorul. |
#23
Posted 14 July 2013 - 14:45
|
#24
Posted 14 July 2013 - 19:11
Mulțumesc pentru feedback și pentru explicații.
1. Să văd dacă am înțeles bine: am considerat o funcție care să simuleze cam ceea ce se petrece acolo când supraîncărcăm operatorul de atribuire. #include <cstdio> // int test(int &a) int& test(int &a) { return a; } int main() { int a = 5; test(a) = 4; printf("%d",a); return 0; } În cazul prototipului comentat (int test()), transmitem o variabilă prin referință, și o returnăm un int, deci o valoare. Ceea ce înseamnă ca test(a) = 4 ar fi 5 = 4, ceea ce nu are sens (compilatorul a dat eroare). În cazul prototipului (int& test()), returnăm o adresă, dar nu dpdv al valorii numerice (0x1A....), ci practic o variabila ”a” în sine? test(a) = 4 observ că va merge. 3. Aha, nu știam că este necesar și un constructor pentru copiere. Voi încerca să implementez unul să văd dacă mai sunt probleme. 4. Nu ar fi redundantă și supraîncărcarea op. += (implementarea funcției)? Dacă supraîncărcăm op. +, precum și op. =, atunci prin a += b, nu ar trebui ca compilatorul să accepte faptul că s-ar petrece a = a + b, pentru că putem folosi deja + și = în astfel de expresii? Am putea în felul acesta să facem un fel de ”compuneri” între operatori? Dar văd că nu prea merge... 5. Hm, păi atunci ar merge să adăugăm în cadrul clasei o variabilă size, care se modifică numai când este apelat constructorul/ + / = / alte operații, iar funcția length() să îi returneze valoarea? |
#25
Posted 15 July 2013 - 07:52
Am rezolvat si eu tema. Daca ai putea arunca o privire si pe la mine ti-as fi recunoscator.
Am facut si o functie care imi afisa sirurile, sa fiu sigur ca functioneaza. Inca n-am inteles cum s-a facut in pagina anterioara, cu cout sa se afiseze membrii clasei polinom. O sa ma mai uit. #include <iostream> #include <cstring> #include <cstdio> using namespace std; namespace MyLib { class String { private: char *sir; public: String(){ } String(const char *sir); ~String(); void operator=(const char *sir); void operator=(String string2); char operator[](int nr); String operator+(String string2); void operator+=(const char *sir); int length(); String subString(int numar); char *toCharPointer(); void print(); }; } // namespace using namespace MyLib; String::~String() { delete [] sir; } void String::print() { cout << sir << endl; } String::String(const char *sir) { this->sir = new char [strlen(sir)+1]; strcpy(this->sir, sir); } void String::operator=(const char *sir) { this->sir = new char [strlen(sir)+1]; strcpy(this->sir, sir); } void String::operator=(String string2) { this->sir = new char [strlen(string2.sir)+1]; strcpy(this->sir, string2.sir); } void String::operator+=(const char *sir) { String auxiliar; auxiliar.sir = new char [strlen(this->sir)+1]; strcpy(auxiliar.sir, this->sir); delete [] this->sir; this->sir = new char [strlen(auxiliar.sir)+strlen(sir)+1]; strcpy(this->sir, auxiliar.sir); strcat(this->sir, sir); } int String::length() { return (strlen(sir)); } char String::operator[](int nr) { return (this->sir[nr]); } String String::operator+(String string2) { String auxiliar; auxiliar.sir = new char [strlen(this->sir)+strlen(string2.sir)+1]; strcpy(auxiliar.sir, this->sir); strcat(auxiliar.sir, string2.sir); return auxiliar; } char* String::toCharPointer() { return (this->sir); } String String::subString(int numar) { String *aux = new String ; aux->sir = this->sir+numar; return *aux; } int main() { String a; a = "Hello "; a.print(); int sizeA = a.length(); cout << sizeA << endl; char litera = a[1]; cout << litera << endl; String b("World"); b.print(); String c; c = a+b; c.print(); c += " din C++"; printf("%s \n", c.toCharPointer()); String d = c.subString(3); d.print(); return 0; } Edited by alexuts56, 15 July 2013 - 07:54. |
#26
Posted 15 July 2013 - 10:45
@adrian93. Ai o mica problema la cod. Norocul tau este ca aceeasi problema a existat si la CString in versiunile initiale. Deci esti intr-o companie selecta .
@alexuts56. Supraincarcarea operatorului de atribuire nu se face cum ai facut tu: void operator=(String string2);ci String& operator=(const String& string2);Motivele au fost expuse in alte postari anterioare. operatorul[] trebuie neaparat sa arunce exceptie. metoda length nu trebuie sa calculeze de fiecare data lungimea. S-a amintit deja. String String::subString(int numar) { String *aux = new String ; aux->sir = this->sir+numar; return *aux; }Aici ai probleme mari, cea mai mare fiind un memory leak de toata frumusetea. Ce se intampla daca sirul initial este schimbat? Ce se intampla cand se sterge obiectul rezultat? void String::operator+=(const char *sir) { [b]String auxiliar; auxiliar.sir = new char [strlen(this->sir)+1];[/b] ... }Motiveaza alegerea tipului pentru variabila auxiliar. @OC si dani.user. Ce parere aveti de o sub-arie in care sa fie puse temele de la tutoriale? Astfel tutorialele ar fi ceva mai aerisite. Edited by Cy_Cristian, 15 July 2013 - 10:45. |
#27
Posted 15 July 2013 - 10:54
"operatorul[] trebuie neaparat sa arunce exceptie."
Nu trebuie sa arunce exceptie, din aceleasi motive pentru care nici std::string::operator [] nu arunca. Dar poate sa creeze o functie at(), care sa verifice accesele out-of-bounds si sa arunce exceptii daca e cazul. Ar fi trebuit sa avem: char& operator[] (size_t pos); const char& operator[] (size_t pos) const; Edited by xyv123, 15 July 2013 - 10:54. |
#28
Posted 15 July 2013 - 11:08
Ne poti explica care sunt motivele pentru care nu se arunca exceptie in caz de OOB in operatorul de indexare al "string"?
Un programel scris prost crapa in VS2008. Acelasi programel merge fara probleme cu gcc. LE: Reformulare. Edited by Cy_Cristian, 15 July 2013 - 11:11. |
|
#29
Posted 15 July 2013 - 11:18
Codul client ar trebui fie sa verifice ca parametrul trimis in operator [] nu e out-of-bounds, fie sa foloseasca at().
Motive: - unul evident, de performanta. Folosind operatorul [], vreau sa accesez caracterul de la un anumit index cat mai rapid. Daca as vrea sa mi se verifice accesul, pot sa folosesc linistit at(). - De obicei, un programator C++ se astepta ca operatorul [] pe secvente sa ofere garantii no-throw. Edited by xyv123, 15 July 2013 - 11:21. |
#30
Posted 15 July 2013 - 11:23
Pe mine ma sperie partea cu bold si italic de aici destul de mult:
Quote
Exception safety If pos is not greater than the string length, the function never throws exceptions (no-throw guarantee). Otherwise, it causes undefined behavior. De unde si implementare din VS2008. |
#31
Posted 15 July 2013 - 11:26
Mi se pare normal.
Edited by xyv123, 15 July 2013 - 11:27. |
#32
Posted 15 July 2013 - 11:29
#33
Posted 15 July 2013 - 12:13
@xyv123.
Eu sunt de principiu ca executia unui program trebuie sa fie determinista. @adrian93. Incearca sa faci. a=a; a+=a; Edited by Cy_Cristian, 15 July 2013 - 12:14. |
|
#34
Posted 15 July 2013 - 12:27
@Cy_Cristian: Ok, mulțumesc pentru observație, am modificat += astfel încât să meargă și în cazul a+=a .
|
#35
Posted 15 July 2013 - 12:31
#36
Posted 15 July 2013 - 13:42
@Cy_Cristian: Multumesc! Am inteles unde am gresit, mai putin faza cu supraincarcarea operatorului de atribuire.
Adica de ce e gresit daca nu returnez nimic? Care-i copia inutila? |
Anunturi
▶ 0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users