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 |
Chestiune interesantă în C++
Last Updated: May 02 2014 11:43, Started by
Googlegps
, Apr 18 2014 23:34
·
0
#1
Posted 18 April 2014 - 23:34
Ceva destul de straniu se întâmplă în C++ (lucru pe care nici măcar profii de facultă nu-l știu).
Să presupunem că avem (abstractizat și conceptual vorbind): - o clasa; - este definit un cast de la clasa respectivă la type-ul întreg (operator int() ). - un operator+ (de adunare) pentru 2 instante ale clasei. Fie ob - un obiect/o instantă a clasei. In programul principal, avem: ob+100 (scriere, whatever..) și 100+ob. În mod normal, majoritatea compilatoarelor aruncă o eroare de ambiguitate având 2 posibilități la fel de bune: - fie transformă obiectul ob în intreg, și face sumare obișnuită (adunare dintre 2 intregi) - fie transformă 100 în obiect al clasei, și face sumare dintre 2 obiecte (prin operator+ definit). Aici apare problema. Unele compilatoare accepta ob+100 dar 100+ob nu, unele (majoritatea) nu acceptă niciuna - eroare de ambiguitate, altele le acceptă pe ambele (și utilizează una din cele 2 posibilități, după ce regulă, nimeni nu știe ). Vreau să spun că aceste compilatoare se comporta diferit. Care ar fi explicația? Acestă temă este în discuție chiar și printre profesorii de facultate . Edited by Googlegps, 18 April 2014 - 23:36. |
#2
Posted 18 April 2014 - 23:54
Googlegps, on 18 aprilie 2014 - 23:34, said:
Ceva destul de straniu se întâmplă în C++ (lucru pe care nici măcar profii de facultă nu-l știu). Să presupunem că avem (abstractizat și conceptual vorbind): - o clasa; - este definit un cast de la clasa respectivă la type-ul întreg (operator int() ). - un operator+ (de adunare) pentru 2 instante ale clasei. Fie ob - un obiect/o instantă a clasei. In programul principal, avem: ob+100 (scriere, whatever..) și 100+ob. În mod normal, majoritatea compilatoarelor aruncă o eroare de ambiguitate având 2 posibilități la fel de bune: - fie transformă obiectul ob în intreg, și face sumare obișnuită (adunare dintre 2 intregi) - fie transformă 100 în obiect al clasei, și face sumare dintre 2 obiecte (prin operator+ definit). Aici apare problema. Unele compilatoare accepta ob+100 dar 100+ob nu, unele (majoritatea) nu acceptă niciuna - eroare de ambiguitate, altele le acceptă pe ambele (și utilizează una din cele 2 posibilități, după ce regulă, nimeni nu știe ). Vreau să spun că aceste compilatoare se comporta diferit. Care ar fi explicația? Acestă temă este în discuție chiar și printre profesorii de facultate . Regula dupa care compilatoarele fac handle diferit la chestia asta mi se pare irelevanta. Pur si simplu au implementari diferite, si deci un behaviour diferit. Nu mi se pare o chestie atat de semnificativa incat sa fi fost nevoie sa fie standardizata. In lumea reala, atunci cand te lovesti de astfel de cod, ceva clar pute, insa nu despre asta discutam. Normal, intr-un limbaj strong-typed, cum e C++ mi s-ar parea sa nu accepte nici una din variante, asa cum ai spus si tu. edit: compilatoarele care dau eroare, nu fac cast automat in momentul in care se face adunarea, de la tipul clasei la intreg, altele fac, doar pe jumatete... Edited by puya4ever, 18 April 2014 - 23:56. |
#3
Posted 19 April 2014 - 01:39
Cum a zis si puya, depinde de implementarea fiecarui compilator. Si in Visual Studio esti lasat sa incluzi stdio.h si teoretic sa lucrezi in C insa accepta functii cu parametru &referinta sau nu stie de popen ci de _popen...
Insa altceva mi-a atras mie atentia Googlegps, on 18 aprilie 2014 - 23:34, said:
Ceva destul de straniu se întâmplă în C++ (lucru pe care nici măcar profii de facultă nu-l știu). Googlegps, on 18 aprilie 2014 - 23:34, said:
Acestă temă este în discuție chiar și printre profesorii de facultate . |
#4
Posted 19 April 2014 - 10:05
Aici apare problema. Unele compilatoare accepta ob+100 dar 100+ob nu, unele (majoritatea) nu acceptă niciuna - eroare de ambiguitate, altele le acceptă pe ambele
E normal sa dea eroare intr-un astfel de caz. C++ -ul are niste reguli clare care trebuie respectate de orice compilator.Acele compilatoare care nu dau eroare au fost implementate gresit. Visual Studio e ok din punctul asta. De curiozitate: care sint compilatoarele alea care aleg de capu' lor? |
#5
Posted 19 April 2014 - 14:24
Isaak, on 19 aprilie 2014 - 10:05, said:
Aici apare problema. Unele compilatoare accepta ob+100 dar 100+ob nu, unele (majoritatea) nu acceptă niciuna - eroare de ambiguitate, altele le acceptă pe ambele E normal sa dea eroare intr-un astfel de caz. C++ -ul are niste reguli clare care trebuie respectate de orice compilator.Acele compilatoare care nu dau eroare au fost implementate gresit. Visual Studio e ok din punctul asta. De curiozitate: care sint compilatoarele alea care aleg de capu' lor? Am să mă interesez în legătură cu acele compilatoare... am să cercetez și eu (nu mai țin minte exact versiunile, dar m-a mirat deosebirea). @potae .. Să știi că eu chiar nu am dormit 2 nopți gândindu-mă la această chestie (m-a tot frământat)! Edited by Googlegps, 19 April 2014 - 14:24. |
#7
Posted 19 April 2014 - 21:24
Încă o chestiune interesanta legată de exprimare.
Ideea pornește de la moșteniri. Aici apar 2 exprimări, care ca efect reprezintă același lucru. Prima, cu care(mâncare), sunt de acord: O clasă moștenește toți membrii publici și protejați ai clasei de bază. Prin urmare, ea nu are acces la membrii privați (că na, de aia sunt privați) prin faptul că aceștia nu sunt nici măcar moșteniți. A doua - nu sunt de acord cu ea - . O clasă moștenește toți membrii din clasa de bază (inclusiv cei privați), iar după aceea (după ce toți membrii sunt moșteniți) membrii privați ai clasei inițiale devin inutilizabili/ (sună al naibii de groaznic, dar da, am auzit-o și pe asta - nu de la un prof de facultă de data asta). Întrebare: ce rol ar mai avea atunci moștenirea membrilor privați.... Vreau aici să subliniez mai mult ideea din spatele mecanismului. Unii consideră că o clasă moștenește toți membrii (toate tipurile de membrii), dar după aceea intervine ideea de private și prin urmare ce a fost private în clasa de bază este inutilizabil (dar există în fond) în clasa moștenitoare. Inutilizabil, dar ea există prin moștenire. Eu consider prima variantă ca fiind corectă (defapt incompletă) având în vedere că nu moștenește constructorii, destructorii, operator =, prietenii. Reformulând ar veni: O clasă moștenește de la clasă de bază toți membrii publici și protejați cu excepția constructorilor, destructorilor, operatorului de atribuire și ai prietenilor. Practic el sare peste tot ce este private in clasa de bază. De curiozitate: De ce fiecare crede ce vrea atunci când programează? Edited by Googlegps, 19 April 2014 - 21:26. |
#8
Posted 20 April 2014 - 11:21
Normal ca vor exista in continuare si membrii privati deoarece clasa mostenitoare poate apela functii ale clasei de baza, ori aceasta are acces la/foloseste si membrii privati.
|
#9
Posted 20 April 2014 - 18:40
Am inteles. Deci ii mosteneste si pe membrii privati ai clasei de baza, doar ca mostenitorul nu are acces direct la ei.(doar prin metode ale clasei de baza)
|
#10
Posted 20 April 2014 - 20:01
Googlegps, on 19 aprilie 2014 - 21:24, said:
Prima, cu care(mâncare), sunt de acord: O clasă moștenește toți membrii publici și protejați ai clasei de bază. Prin urmare, ea nu are acces la membrii privați (că na, de aia sunt privați) prin faptul că aceștia nu sunt nici măcar moșteniți. Imagineaza-ti ca ai o clasa oarecare ce are printre altele o variabila privata name si o functie publica setName ce va atribui un nume varibilei private. Acum imagineaza-ti ca se deriva o alta clasa, care evident va mosteni functia setName. Daca variabila privata nu e mostenita deloc, unde crezi ca va fi stocat acel nume? |
|
#11
Posted 20 April 2014 - 20:10
Am inteles. Practic, se mostenesc si membrii privati DAR acestia nu vor putea fi utilizati de metodele proprii clasei mostenitoare (putand fi accesate doar de metodele mostenite).
E interesanta ideea că se moștenește private-ul de la clasa de bază, dar membrii proprii clasei derivate NU o pot utiliza (doar metodele mostenite) Edited by Googlegps, 20 April 2014 - 20:13. |
#12
Posted 20 April 2014 - 21:36
Gandeste-te la o clasa precum la o structura.
Clasa de baza stocheaza parametrii x, y, z in primele pozitii din memorie. Clasa derivata stocheaza parametrii x, y, z iar dupa ei mai stocheaza a, b, c. Cum clasa derivata trebuie sa poata fi oricand cast-uita la clasa de baza, acest lucru se realizeaza foarte simplu, cine foloseste un pointer la clasa derivata dar nu stie decat ca e o clasa de baza, poate bine-mersi accesa parametrii x, y, z fiindca-s tot la inceputul zonei de memorie ocupata de clasa/structura. private/public/protected sunt doar mecanisme ale compilatorului de a-ti da peste degete daca vrei sa faci ceva nepermis |
#13
Posted 24 April 2014 - 15:00
Faptul ca declari un membru ca fiind privat nu faci altceva decat de a-l ascunde si nicidecum de a impiedica mostenirea acestuia.
De fapt public, protected si private sunt rezultatul direct al incapsularii. |
#14
Posted 02 May 2014 - 11:43
Googlegps, on 20 aprilie 2014 - 20:10, said:
Am inteles. Practic, se mostenesc si membrii privati DAR acestia nu vor putea fi utilizati de metodele proprii clasei mostenitoare (putand fi accesate doar de metodele mostenite). E interesanta ideea ca se mo?tene?te private-ul de la clasa de baza, dar membrii proprii clasei derivate NU o pot utiliza (doar metodele mostenite) #include <iostream> class A { private: int a; public: A():a(0) {} void printA() { std::cout << "a privat din A este: " << a << "\n"; } }; class B: public A { private: int b; public: B():b(-1) {} /* o mare prostie, fac cast la inceputul obiectului in memorie si pentru ca il mosteneste pe A, inseamna ca exista un int in memoria obiectului si il scriu subscriu cu 3 deci int a exista in memoria oricarui obiect de tip B */ void porcarie() { int* a = reinterpret_cast<int*>(this); *a=3; } void printB() { std::cout << "b privat din B este: " << b << "\n"; } }; int main() { //daca sizeof(int) == 4 (32 biti) atunci: std::cout << sizeof(A) << "\n"; //4 std::cout << sizeof( << "\n"; //8, deci avem si int a si int b B b; b.printA(); // 0 b.printB(); // -1 b.porcarie(); b.printA(); // 3 !!! am modificat variabila privata a clasei A printr-un obiect de tip B b.printB(); // -1, asta a ramas la fel return 0; };https://ideone.com/6QASds arata ca returneaza cum am zis mai sus. Daca nu intelegi ceva, te rog sa imi spui. Googlegps, on 18 aprilie 2014 - 23:34, said:
- fie transforma 100 în obiect al clasei, ?i face sumare dintre 2 obiecte (prin operator+ definit). Nu ar trebui sa transforme 100 in obiect al clasei decat daca clasa are un constructor care primeste un int dar nu este declarat cu explicit. De aici cred ca e confuzia ta. Daca nu stii ce e ala atunci ar fi bine inainte sa te uiti aici: http://en.cppreferen...nguage/explicit Cazul fara constructor explicit: class A { int m_A; public: A( int i = -1 ):m_A(i) {} operator int() { return m_A; } A operator+(const A& a) { A rez; rez.m_A = a.m_A + m_A; return rez; } }; int main() { A a; A x = 1+a; // apeleaza operatorul int() si pe urma constructorul A A y = a+1; // nu are de ce sa mearga, eroare de ambiguitate /* * daca se comenteaza operatorul int(), se face 1 obiect al clasei A si se apeleaza A operator+ dar nu mai merge adunarea de sus * daca se comenteaza operatorul A operator+, se face cast la int si se face adunare de 2 int-uri si merge si adunarea de sus */ return 0; } iar cu explicit: class A { int m_A; public: explicit A( int i = -1 ):m_A(i) {} operator int() { return m_A; } A operator+(const A& a) { A rez; rez.m_A = a.m_A + m_A; return rez; } }; int main() { A a; int x = 1+a; // apeleaza operatorul int() si face adunare intre 2 intregi int y = a+1; // apeleaza operatorul int() si face adunare intre 2 intregi return 0; }Daca nu de aici era problema, te rog sa imi spui . PS: Cum fac sa fie codul colorat ? |
Anunturi
▶ 0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users