Ako vratit referenciu – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Ako vratit referenciu – C / C++ – Fórum – Programujte.comAko vratit referenciu – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Martin
~ Anonymní uživatel
1377 příspěvků
5. 8. 2014   #1
-
0
-

Ahojte hclapi.....potrebujem aby mi tento kod vratil referenciu.....a stale neviem co tam mam zle.....

#include <iostream>
#include <ctime>
#include <cmath>

using namespace std;

char & buildstr(char & ch, int n);

int main()
{
    char ch;
    int n;
    
    cout << "Zadajte pismeno: ";
    cin >> ch;
    cout << "Zadajte kladne cislo: ";
    cin >> n;
    
    char & p = buildstr(ch, n);
    cout << p << endl;

    system("pause");
    return 0;
}

char & buildstr(char & ch, int n)
{
    char* p = new char[n + 1];
    p[n + 1] = '\0';
    
    while (n-- > 0)
          p[n] = ch;
          
    return p;
}

ak funkciu prepisem na 

char* buildstr(char & ch, int n) vsetko ide ako ma, samozrejme po zmene aj v main() ale ved takto by to malo tiey fungovat....preco to neide?

Nahlásit jako SPAM
IP: 159.51.236.–
Reklama
Reklama
KIIV+42
God of flame
5. 8. 2014   #2
-
0
-

no referenci muzes vratit jakozto  return *p;  ale otazkou je, jestli ti tim nevznikne pak memory leak, protoze ten pointer musis taky nekdy v budoucnu uvolnit

krom toho char * a char & je pomerne rozdil.. v char * muze byt cele pole ale char & je vlastne jen jedinej znak

+ p[n + 1] = '\0'; je zapis mimo pole

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
5. 8. 2014   #3
-
0
-

#2 KIIV
Prave som tu studoval a prave kvoli tomu to nepojde......lebo ja potrebjem vratit pole znakov......do programu zadas znak a cislo.....a na vystupe sa ti vypise znak tolkokrat kolko bola zadana ciselna hodnota......iba som chcel ci je mozne ten program prerobit aj na referenciu.....ale ako vidim bez novej obluznej funkcie ktora prijima tu referneciu, to nepojde.....

takto....

#include <iostream>
#include <ctime>
#include <cmath>

using namespace std;

char* buildstr(char & ch, int n);

int main()
{
    char ch;
    int n;
    
    cout << "Zadajte pismeno: ";
    cin >> ch;
    cout << "Zadajte kladne cislo: ";
    cin >> n;
    
    char* p = buildstr(ch, n);
    cout << p << endl;
    delete [] p;

    system("pause");
    return 0;
}

char* buildstr(char & ch, int n)
{
    char * p = new char[n + 1];
    p[n + 1] = '\0';
    
    while (n-- > 0)
          p[n] = ch;
    
    return p;
}

toto funguje ako ma......

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
5. 8. 2014   #4
-
0
-

a co ti brani pouzit #include <string> a:

string filled(n,ch);

cout << filled << "\n";

?

pak se nemusis starat ani o tu pamet, protoze je to staticky string...

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
5. 8. 2014   #5
-
0
-

#4 KIIV
Ja sa zatial C++ iba ucim.....idem podla knihy...nevies mi poradit nejaku dobru knihu, kde by boli riesene priklady na ktorych by som ziskal prax?

A mockrat dakujem za rady....

Dakujem

Nahlásit jako SPAM
IP: 77.48.69.–
KIIV+42
God of flame
5. 8. 2014   #6
-
0
-

#5 Martin
priklady z praxe? to je narocny - v praxi jsou obvykle komplexni problemy a blbe se z toho delaji priklady - natoz do knih.

kazdopadne plati to, ze kde to jde, je lepsi pouzit knihovny pred vlastnim kodem (kazdy radek vlastniho kodu muze a casto i bude implementovat nejakou chybu (coz je u tebe napriklad to p[n + 1] = '\0';))

a spis napis o co se teda vlastne snazis a proc tam tak nutne potrebujes zrovna vracet referenci.. nestacilo by to vyplnit do predaneho pointeru?

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
6. 8. 2014   #7
-
0
-

#6 KIIV
Nie priklady z praxe....nejaku knizku kde by boli zadania uloh samozrejme aj s vypracovanim na overenie.....

pockaj toto podla mna nie je chyba, ved ja som tu vytvoril novy ukazatel s hodnotou o 1 vyssie na ukoncovaci znak pola char

 char * p = new char[n + 1];
    p[n + 1] = '\0';
Ja sa prave ucim z knihy a snazim sa presne pochopit ako pracuju referencie, ukazatal mi je uplne jasny (aspon myslim) ale referencie je nieco podobne, len som nevedel ze dokaze ukazovat iba na jeden prvok.....ved ukazatale na char[] je adresa prveho prvku, ale ako teda pracuje ked mam referenciu na strukturu. Ta tiez iba ukazuje na 1 prvok, ale nedokazem sa dostat na iny ako u ukatazeta ze pricitam 1 bajt k adrese, ze? Lebo referenciu musim pri deklaracii priamo priradit typu

int a = 5;

int & pa = a;

tymto som vlastne povedal ze pa je to iste ako a, maju tu istu hodnotu aj adresu......a hlavne ako aj ukazatele pracuju s originalom a nerobia kopiu.

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
6. 8. 2014   #8
-
0
-

vytvoril si pole o n+1 znacich ...  dejme tomu n=4 takze mas misto na 5 znaku..

1. znak je na indexu 0

2. znak je na indexu 1

3. znak je na indexu 2

4. znak je na indexu 3

5. znak je na indexu 4   (tudiz posledni znak je tady, ne az na indexu 5 - to uz je mimo pole)

reference jsou lepsi k predavani parametru do funkci (aby se zmena uvnitr projevila i na vne funkce), ale pouzivaji se i treba u cin/cout, aby se dal zretezit operator << .. << .. - bez toho, aby to vratilo referenci samo na sebe by to neslo udelat

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
6. 8. 2014   #9
-
0
-

#8 KIIV
To mas pravdu.....dam znak 'l' potom pocet kolkokrat sa ma vzpisat 3x.....0, 1, 2 - su tri ale predsa ked vraciam adresu na char[] potrebujem mat posledny znak ktory ukoncuje retazec, nie? teda tento '\0' - ktory znaci koniec a preto potrebujem mat n + 1 aby som mal

0 = l

1 = l

2 = l

3 = '\0'

teda tak to tvrdi kniha podla ktorej sa ucim....Mistrovstvi v C++ od Stephena Prata

ved ja som si vztvoril novy ukazatel na dynamicke pole znakov chr* p = new char[n + 1]

tak je to dobre ci nie.....?

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
6. 8. 2014   #10
-
0
-

to ano .. das char * pole = new char[n+1];   ale jen   pole[n] = '\0';

Nahlásit jako SPAM
IP: 212.80.65.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mitti0
Newbie
6. 8. 2014   #11
-
0
-

#10 KIIV
Vlastne ano, mas pravdu,. tam ma to nehrklo......

Nahlásit jako SPAM
IP: 159.51.236.–
Martin
~ Anonymní uživatel
1377 příspěvků
6. 8. 2014   #12
-
0
-

#11 mitti
A fakt nevies o ziadnej cvicebnici s ulohami?

Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
6. 8. 2014   #13
-
0
-
Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
6. 8. 2014   #14
-
0
-
Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
6. 8. 2014   #15
-
0
-

.cpp soubory se NIKDY neincludujou do sebe.. zkompiluji se samostatne do .o a pak se slinkujou do vysledny binarky... nicmene pokud budes mit neco v obou cpp souborech, tak to neprojde (vse globalni muze byt jen v jedinem souboru a pokud chces videt nejakou promennou pres vice souboru, tak od toho je ten extern, u prototypu funkci to nevadi)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
7. 8. 2014   #16
-
0
-

#15 KIIV
#12 Martin
OK....ale podla knihy mam toto.....

tak ako to mam prerobit ak chcem mat 3 subory aby to islo? Ak aj ten file2.cpp premenujem na file2.h tak to nefunguje.....prosim porad....som uz bezradny

1. main.cpp

#include <iostream>
#include "coordin.h"

using namespace std;

int main()
{
    rect rplace;
    Polar pplace;
    
    cout << "Zadajte hodnoty x a y: ";
    while (cin >> rplace.x >> rplace.y)
    {
          pplace = rect_to_polar(rplace);
          show_polar(pplace);
          cout << "Zadajte dalsie dve cisla <q pre ukoncenie>: ";
    }
    
    system("pause");
    return 0;
}

2. subor: coordin.h

#include <iostream>
//structure template
struct Polar
{
     double distance;
     double angle;
};

struct rect
{
       double x;
       double y;
};

//prototypy
Polar rect_to_polar(rect xypos);
void show_polar(Polar dapos);

3. subor: file2.cpp

#include <iostream>
#include <cmath>
#include "coordin.h"

//funkcie volane hlavnym programom
using namespace std;

Polar rect_to_polar(rect xypos)
{
      Polar answer;
      answer.distance = sqrt(xypos.x * xypos.x * + xypos.y * xypos.y);
      answer.angle = atan2(xypos.y, xypos.x);
      
      return answer;
}

void show_polar(Polar dapos)
{
     const double Rad_to_deg = 57.29577951;
     
     cout << "vzdialenost = " << dapos.distance;
     cout << ", uhol = " << dapos.angle << endl;
}

Připojen obrázek.

Připojen obrázek.

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
7. 8. 2014   #17
-
0
-

nevim v cem to sice delas, me to pekne proslo:

$ g++ -c -o main.o main.cpp 
$ g++ -c -o file2.o file2.cpp 
$ g++ file2.o main.o -o test
$ ./test
Zadajte hodnoty x a y: 10 22
vzdialenost = 220, uhol = 1.14417
Zadajte dalsie dve cisla <q pre ukoncenie>: q
Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
7. 8. 2014   #18
-
0
-

#17 KIIV
V Dev c++

Nahlásit jako SPAM
IP: 77.48.69.–
Doomista+1
Stálý člen
7. 8. 2014   #19
-
0
-

#4 KIIV
teď jste mi s tou pamětí nasadili brouka do hlavy celkem. Mám-li tedy kód:
 

int *udelejPoleJednicek(int delka){
int *result=new int[delka];
	for(int i=0; i<delka; i++) result[i]=1;
return result;
}
//....
int *ptr=udelejPoleJednicek(10);

Musím potom na konci bloku kódu, pro který ptr existuje ten ptr nějak uvolňovat, nebo mi to C++ zařídí samo? A pokud ho mám uvolňovat, mám použít delete ptr; nebo ptr=NULL; (nebo pro jistotu oboje)?
Tenhle přístup používám ve hrách strašně často a nikdy mě ten pointer nenapadlo nějak uvolňovat.

Nahlásit jako SPAM
IP: 90.176.176.–
Na vše stačí iostream...
KIIV+42
God of flame
7. 8. 2014   #20
-
0
-

#19 Doomista
k  typ * ptr = new typ[delka];   patri vzdy nejaky   delete [] ptr;  a pokud s tim jeste muzes nekde dal pracovat, tak i pro jistotu  ptr=NULL;

neni to jeste takovy problem u neceho, co se jen zapne a vypne (nebo se to na zacatku zabere, ale vickrat se to neudelat) - za to u sluzeb a programu, kde by se to stalo kazdou akci nebo tak, tak uz je to docela problem (obzvlaste pokud by to bylo hodne dat a nebo hodne casto)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV+42
God of flame
7. 8. 2014   #21
-
0
-

#18 Martin
dev-c++ by melo umet, ze kdyz pridas do projektu dalsi cpp sobor, tak ho zkompiluje samostatne a pak se to vse slinkuje do jednoho (tj v zadnym pripade neincludovat do jineho souboru - na includy jsou .h)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Doomista+1
Stálý člen
7. 8. 2014   #22
-
0
-

#20 KIIV
Jop, máš svatou pravdu. Ověřování tohoto mého osobního mýtu mě teď stálo tvrdý restart počítače, když jsem se očividně pokusil přidávat na RAM data přibližnou rychlostí 2TB/s  

Fascinuje mě, že se mi to ještě nikdy nevymstilo, většinou to používám na proměnné, které trvají po celou dobu programu, ale stejně budu muset udělat menší úpravy v enginu. Díky za cennou radu  

Nahlásit jako SPAM
IP: 90.176.176.–
Na vše stačí iostream...
Martin
~ Anonymní uživatel
1377 příspěvků
7. 8. 2014   #23
-
0
-

#21 KIIV
No mne to stale nefunfuje. Stale to vyhadzuje tu istu chybu:

  [Linker error] undefined reference to `rect_to_polar(rect)' 

  [Linker error] undefined reference to `show_polar(Polar)' 

  ld returned 1 exit status 

Připojen obrázek.

Nahlásit jako SPAM
IP: 77.48.69.–
KIIV+42
God of flame
7. 8. 2014   #24
-
0
-

a mas to v jednom projektu?

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
7. 8. 2014   #25
-
0
-

#24 KIIV
tak preve som na to prisiel a pozeral, co si napisal.....suksil som vytvorit novy projekt a vsetko tam nahrat a uz to frci :-)......

Co si on vytvara v projekte.....ked to bez toho neide?

Nahlásit jako SPAM
IP: 77.48.69.–
hlucheucho+10
Posthunter
7. 8. 2014   #26
-
0
-

máš nastavené include path?

hu

Nahlásit jako SPAM
IP: 193.86.81.–
Martin
~ Anonymní uživatel
1377 příspěvků
7. 8. 2014   #27
-
0
-

#26 hlucheucho
to sa kde nastavuje jaku myslis #include <path>?

Nahlásit jako SPAM
IP: 77.48.69.–
KIIV+42
God of flame
7. 8. 2014   #28
-
0
-

#25 Martin
dela si tam Makefile, projede vsechny cpp soubory a zkompiluje jednotlive a na zaver to slinkuje.. neco jako sem delal ja rucne

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
8. 8. 2014   #29
-
0
-

include path se nastavují ve vlastnostech projektu. Určují ve kterých adresářích překladač hledá hlavičkové soubory.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
Martin
~ Anonymní uživatel
1377 příspěvků
8. 8. 2014   #30
-
0
-

#29 hlucheucho
Aha, dakujem za rady uz je to aplikovane a terza dalsi dotaz.......Idem podla knihy.....

je lepsie pouzivat

using namespace std; a mat vsetko global

alebo radsej takto:

using std::cin;

using std::cout;

using std::endl;

lebo ten druhy sposob je strasne zdlhavy a v knihe pisu ze je to najlepsie....ale asi iba z toho dovodu ak by som nahodou vytvoril funkciu s rovnakym menom abz ju nehladam v kniznici STD.....je to tak?

Tak ktory sposob?

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
8. 8. 2014   #31
-
0
-

#30 Martin
sablony a header files bez

ve tvym kodu je to vesmes jedno

kazdopadne ve vetsim projektu to neni dobre michat pomoci using namespace ..

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mitti0
Newbie
8. 8. 2014   #32
-
0
-

#31 KIIV
stale neviem kde robim chybu, obcas to ide a obcas nie....terez mi ho nechce ani za svet nalinkovat aj ked som si vytvoril novy projekt a vsetko tam dal ako ma byt......

Ak to dam vsetko dohromady, tak to ide, ale oddelene, ani za svet.....

Aj include path uz mam nastaveny na potrebny adresar......

Připojen obrázek.

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
8. 8. 2014   #33
-
0
-

#32 mitti
a kde mas header file s definici objektu?

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mitti0
Newbie
8. 8. 2014   #34
-
0
-
Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
8. 8. 2014   #35
-
0
-

no tady je zrovna ukazka toho, co se do header souboru musi dat (a nebo musis mit to same taky ve druhem souboru), ale header file je na to vhodnejsi

(tim myslim dat tam JEN to co mas ted pred main - je to vlastne interface a prekladac ho musi znat i v tom stocks.cpp)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mitti0
Newbie
8. 8. 2014   #36
-
0
-

#35 KIIV
Takze ta definicie triedy musi byt aj v stocks.cpp aj v main.cpp? Lebo ak to nemam aj tam aj tam tak to neide.....a akto to ma byt uplne najlepsie, aby to bolo spravne, ale prosim polopatisticky

Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
8. 8. 2014   #38
-
0
-

ne .. hlavicku includuj i do toho stocks.cpp stejne jako ji mas v main.cpp

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
12. 8. 2014   #39
-
0
-

#38 KIIV
Tak nakoniec som zmenil IDE na VIdual studio 2013 Express, len mam jeden dotaz, ako dokazem ist step by step v programe aby mi program neskakal aj do kniznic isteam a osteam?

Je to vobec vo VS mozne? Lebo ak som robil v C#, tak mi to neskakalo do kniznic .NET framworks?

Dakujem

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
12. 8. 2014   #40
-
0
-

vs neznam, nepouzivam zadny ide

ale obvykle je tam step into, step over nebo neco na tom principu.. proste jestli se ma zanorit, nebo jen vykonat ten radek

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martin
~ Anonymní uživatel
1377 příspěvků
12. 8. 2014   #41
-
0
-

#40 KIIV
Jasne, to viem, ja len ze ak som robil program v C#, tak ak som dal Step into, tak to neslo do triedy napr.....Collection, iba do mojej triedy.....a motody ktore som vyuzival z triedy Collection to iba spracovali, bez toho aby som sa cez ne musel preklikavat.....ale v C++ to hned vlezie aj do modet, ktore spracuvaju vstup, atd....a neviem preco

Nahlásit jako SPAM
IP: 159.51.236.–
Doomista+1
Stálý člen
12. 8. 2014   #42
-
0
-

Zkus si udělat break point na začátku mainu. Klikni levým myšítkem na tmavej pásek vlevo od čísel řádků a pak normálně spusť debug, provádění se zarazí na breakpointu a pak můžeš jít step by step

Nahlásit jako SPAM
IP: 90.176.176.–
Na vše stačí iostream...
KIIV+42
God of flame
12. 8. 2014   #43
-
0
-
Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mitti0
Newbie
12. 8. 2014   #44
-
0
-
Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
12. 8. 2014   #45
-
0
-

#44 mitti

Uz to facha....tu je navod, uplne na samom spodku, ak by niekto potreboval....treba vytvorit novy filter

http://stackoverflow.com/questions/21836465/how-to-skip-debugging-all-of-std-namespace-in-visual-c-2013

Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
12. 8. 2014   #46
-
0
-

#43 KIIV


Ahojte mam dalsi dotaz....mam takuto triedu......ktora pouziva pretazenie operatora + na scitanie 2 casov.....

#ifndef _MYTIME_H_
#define _MYTIME_H_
class Time
{
private:
	int hours;
	int minutes;
public:
	Time();
	Time(int h, int m);
	~Time();
	void AddHr(int h);
	void AddMin(int m);
	void Reset(int h = 0, int m = 0);
	Time operator+(const Time & t) const;
	void Show() const;
};
#endif

ja osobne by som ju prepisal takto, aby vracala referenciu na objekt Time

#ifndef _MYTIME_H_
#define _MYTIME_H_
class Time
{
private:
	int hours;
	int minutes;
public:
	Time();
	Time(int h, int m);
	~Time();
	void AddHr(int h);
	void AddMin(int m);
	void Reset(int h = 0, int m = 0);
	Time & operator+(const Time & t) const;
	void Show() const;
};
#endif

Ale v knihe je pisane: citujem: ze to tak urobit nemozeme, lebo funkcia vytvori novy objekt Time(sum) ako sucet dvoch objektov Time. Vratenie objektu program vytvori jeho kopiu, ktoru moze pouzit volajuca funkcia. Keby vsak navratovy typ bola referencia na Time odkazovala by na objekt sum. Objekt sum je vsak lokalna premenna a je pri ukonceni funkcie znicena, takze referencia by bola na neexistujuci objekt....

Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
12. 8. 2014   #47
-
0
-

#46 mitti
inak metody

#include <iostream>
#include "mytime.h"

using namespace std;

Time::Time()
{
	hours = minutes = 0;
}

Time::Time(int h, int m)
{
	hours = h;
	minutes = m;
}

Time::~Time()
{
}

void Time::AddHr(int h)
{
	hours += h;
}

void Time::AddMin(int m)
{
	minutes += m;
	hours += minutes / 60;
	minutes %= 60;
}

void Time::Reset(int h, int m)
{
	hours = h;
	minutes = m;
}

Time & Time::operator+(const Time & t) const
{
	Time sum;
	sum.minutes = t.minutes + minutes;
	sum.hours = hours + t.hours + sum.minutes / 60;
	sum.minutes %= 60;
	return sum;
}

void Time::Show() const
{
	cout << hours << " hodin, " << minutes << " minut." << endl;
}

Mne ide hlavne o to, ved to je blbost ze nemozem vracat referenciu, vsak ja vytvorim v metode sum, novy objekt typu Time a ten vraciam ako referneciu do man ma vytvoreny objekt, nie? tym padom povodny objekt niekam ukazoval, a ja som mu prepisal referenciu....ci to chapem zle?

Tak ako ze bude zmazana referencia....

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
12. 8. 2014   #48
-
0
-

#46 mitti
ono by to mozna i slo ale je dost nezadouci aby ti operator+ neco menil v argumentech (coz tim docilis).

Jinak referenci na lokalni staticky objekt vratit nemuzes - protoze opravdu prestane existovat jakmile skocis mimo tu metodu. (resp pokud to necistis, tak to tam muze byt jeste na moment nez se to prepise necim jinym - ale vetsinou ti to stejne prekladac nepovoli)

a c++11 by to mela pouzit move konstruktor

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mitti0
Newbie
12. 8. 2014   #49
-
0
-

#48 KIIV
Tak, ako je mozne, ze toto prejde normalne

#include <iostream>
#include "mytime.h"

using namespace std;

int main()
{
	Time A;
	Time B(5, 40);
	Time C(2, 55);
	A.Show();
	B.Show();
	C.Show();
	A = B.operator+(C);
	cout << endl;
	A.Show();
	B.Show();
	Time D;
	D = A.operator+(B);
	D.Show();

	system("pause");
	return 0;
}
Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
12. 8. 2014   #50
-
0
-

#49 mitti
kdo vi, treba tam nemas destruktor, kterej by to nejak poskodil...

nebo to vs dela nejak jinak.. tezko rict

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mitti0
Newbie
12. 8. 2014   #51
-
0
-

#50 KIIV
Ved je tam aj destruktor 

#include <iostream>
#include "mytime.h"

using namespace std;

Time::Time()
{
	hours = minutes = 0;
}

Time::Time(int h, int m)
{
	hours = h;
	minutes = m;
}

Time::~Time()
{
}

void Time::AddHr(int h)
{
	hours += h;
}

void Time::AddMin(int m)
{
	minutes += m;
	hours += minutes / 60;
	minutes %= 60;
}

void Time::Reset(int h, int m)
{
	hours = h;
	minutes = m;
}

Time & Time::operator+(const Time & t) const
{
	Time sum;
	sum.minutes = t.minutes + minutes;
	sum.hours = hours + t.hours + sum.minutes / 60;
	sum.minutes %= 60;
	return sum;
}

void Time::Show() const
{
	cout << hours << " hodin, " << minutes << " minut." << endl;
}

a este ma napadaju tieto otazky: a ked robim step into, tak aj ten prejde akonahle vracia objekt return sum.

Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
12. 8. 2014   #52
-
0
-

#50 KIIV
Takze, po odskusani v Dev C++ to sice zbehne ale su namiesto casov hovadiny.....lebo sa fakt referencia stratila......asi ostanem nakoniec pri Dev C++, lebo VS2013 sa neda verit.....

Je fakt divne ze tam to ide normalne

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
12. 8. 2014   #53
-
0
-

mas tam sice destruktor, ale nic nedela.. zkus v destruktoru cas treba vynulovat (kazdopadne se to nedoporucuje, protoze neni definovano co se stane)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
12. 8. 2014   #54
-
0
-

#52 mitti
Skus sa pozret ako sa volaju destructory:

#include <iostream>


struct Test{
	Test(const Test& x){std::cout << this << "->Test(const Test& == " << &x << ");\n";}
	Test(Test&& x){std::cout << this << "->Test(Test&& == " << &x << ");\n";}
	Test(){std::cout << this << "->Test();\n";}
	~Test(){std::cout << this << "->~Test();\n";}
};

const Test& fnc(const Test& test){
	return test;
}

int main(){

	std::cout << "\n1.\n";
	{
	std::cout << "begin\n";
	const Test& test = Test();
	
	std::cout << "do...\n";
	}
	//--------------------------------------
	std::cout << "\n2.\n";
	{
	std::cout << "begin\n";
	const Test& test = fnc(Test());
	
	std::cout << "do...\n";
	}
        //--------------------------------------
	std::cout << "\n3.\n";
	{
	std::cout << "begin\n";
	Test test = fnc(Test());
	
	std::cout << "do...\n";
	}
	
	
	std::cin.get();
	return 0;
}

Edit:

Tvoja trieda obsahuje az 2 premenne typu int, AZ 2!!! Kludne mozes vracat priamo objekt a nie referenciu :)

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
mitti0
Newbie
12. 8. 2014   #55
-
0
-

#54 vitamin
ja rozumiem preco nemozem vracat referenciu, lebo by som vracal referenciu na lokalnu premennu, a ked ta metoda skonci, hned sa vola destruktor, ktory automaticky tu premennu znici.....

Mne len neide do hlavy, preco to Visual Studio povoluje, ked Dev C++ nie......

Nahlásit jako SPAM
IP: 159.51.236.–
vitamin+8
Grafoman
12. 8. 2014   #56
-
0
-

Rvalue premenne su implicitne konvertovatelne na const&.

Funkcia ktora ma ako parameter premennu typu const& nevie ci ten parameter je lvalue alebo rvalue, takze kompilator ti nemoze povedat ze je tam problem a umozni ti vratit tuto referenciu.

Takto vratena referencia uz nie je brana ako rvalue, takze kompilator nerosiri jej platnost na cely scope, ale zavola destructor po ukonceni vyrazu. 

V c++ je ovela viac svinstiev ako toto, casom si zvyknes :)

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
mitti0
Newbie
12. 8. 2014   #57
-
0
-

#54 vitamin
Inak teraz si prechadzam co si mi polal ten zdrojak a som z toho magor....ako sa to vyhodnocuje.......tymto si ma dostal.....

Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
12. 8. 2014   #58
-
0
-

#56 vitamin
Vobec tomu kodu nerozumiem co si mi poslal, ja som myslel ze v strukture mozu byt iba premenne typu, int atd.

Ale ty to mas pokial tomu aspon trosku rozumiem:

Test(const Test& x){std::cout << this << "->Test(const Test& == " << &x << ");\n";}

mas Strukturu Test a v nej su metody ktore ako parameter prijimaju napr. conkastnu referenciu na nu samotnu...je to tak?

Nahlásit jako SPAM
IP: 159.51.236.–
vitamin+8
Grafoman
12. 8. 2014   #59
-
0
-

#57 mitti
bod 1: vytvori Docasnu premennu (rvalue) Test() a priradiu ju do premennej test ktora ma typ const Test&. Kedze je to referencia tak kompilator rozsiri platnost docasnej premennej na cely scope, take sa nezavola destructor hned po ukonceni vyrazu ale az na konci scopu (blocku)

bod 2: Toto je ukazka blbeho fungovania, najprv sa vytvori docasna premenna Test() ktora je rvalue, ale pretypuje sa na const&. Nasledne sa zavola funkcia fnc ktora nevie ze parameter je docasna premenna a vrati ju. Nasledne vo funkcii main je vratena referencia priradena do premennej test, main ale nevie co vrati funkcia fnc, takze nerzsiri platnost docasnej premennej na cely scope a destructor docasnej premennej sa zavola hned po skonceni vyrau.

bod3: Toto sa podoba bodu 2, len s tym rozdielom ze premenna test nie je referencia, cize sa vola copy constructor a az potom sa vola destructor docasnej premennej Test(), lokalna premenna test sa rusi az na konci scopu, cie vsetko funguje ako ma

 

struct Test{
	Test(const Test& x){std::cout << this << "->Test(const Test& == " << &x << ");\n";}  //copy constructor
	Test(Test&& x){std::cout << this << "->Test(Test&& == " << &x << ");\n";}	//move constructor c++11, c++14
	Test(){std::cout << this << "->Test();\n";}   //obycajny constructor
	~Test(){std::cout << this << "->~Test();\n";}	//destructor
};

struct S{
    //...
    
};
//je to iste ako:
class S{
    public:
        //...
};
Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
mitti0
Newbie
12. 8. 2014   #60
-
0
-

#59 vitamin

mal by si cas napr. na Skype, ze by sme to trosku rozobrali, nech mam v tom jasno? Ale tu na fore sa tusim neda nikde napisat sukromna sprava,......

mohol by si mi prosim napisat tvoije Skype meno na mmittak@gmail.com? a dopist kedy by si mal na mna chvilku?

Dakujem

Nahlásit jako SPAM
IP: 159.51.236.–
vitamin+8
Grafoman
12. 8. 2014   #61
-
0
-

Skype nemam, otazky napis sem, moze ti na ne odpovedat viac ludi. 

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Martin
~ Anonymní uživatel
1377 příspěvků
12. 8. 2014   #62
-
0
-

#61 vitamin
Ja om totiz nikdy nevidel taky zapis struktury a preto by som potreboval trosku obsirnejsi vyklad toho, co to v tej strukture presne je......a hlavne aj to volanie v main()......ale tzm obsirnejsim mzslim fakt, co je presne je......a co kam ide atd......

Dakujem vopred chlapi

potom take drobnosti ktore su &&

Nahlásit jako SPAM
IP: 77.48.69.–
vitamin+8
Grafoman
12. 8. 2014   #63
-
0
-

#62 Martin
struktura a trieda je to iste, jediny rozdiel je v tom ze prvky v triede su defaultne privatne a v strukture su defaultne verejne, v klude mozes mat strukturu ktora dedi triedu a opacne triedu co dedi strukturu...

&& je rvalue referencia, ak si zaciatocnik tak sa tymto druhom referencii zatial nezaoberaj.

#include <iostream>


struct Test{
	Test(){
		//tento constructor sa spusti pri vytvarani triedy, napr:
		//		Test test;
		//		Test test{};
		//		Test test = Test();
		//		(Test());
		//...
		
		//pomocny vypis ktory vypise adresu vytvaranej premennej:
		std::cout << "construct " << this << '\n';	
	}
	
	Test(const Test& x){
		//kopirovaci konstruktor, spusta sa pri kopirovani objektu:
		//		Test a;
		//		Test b = a;	//ako keby si zavolal      b.Test(a);
		//		
	
		//pomocny vypis ktory vypise adresu parametra x a adresu this
		std::cout << "prekopiruje " << &x << " do premennej " << this << '\n';
	}
	
	
	~Test(){
		//destructor, spusta sa pri zaniku objektu:
		//		{
		//			Test a;
		//			
		//			//...	
		//		}	//na konci bloku sa avola destructor a.~Test();
		//		
		//		{
		//			(Test());	//Destructor pre docasnu premennu Test() sa vola hned za vyrazom 
		//			
		//		}
		//
		//
		
		//
		//pomocny vypis ktory vypise adresu this
		std::cout << "destroy " << this << '\n';
	}
	
	void do_something()const{
		//tato funkcia len vypise adresu this, ak sa zavola destructor pre premenu this skor ako sa zavola do_something tak je v programe chyba lebo objekt uz neexistuje
		
		std::cout << "do something " << this << '\n';	
	}

};

const Test& fnc(const Test& test){
	return test;
}

int fnc(const int& i){return i;}

int main(){


	{
		std::cout << "\n\n1. test:\n";
		const Test& test = Test();
		test.do_something();
			
	}
	
	{
		std::cout << "\n\n2. test:\n";
		const Test& test = fnc(Test());
		test.do_something();
	}
	
	{
		std::cout << "\n\n3. test:\n";
		Test test = fnc(Test());
		test.do_something();
	}
	
	std::cin.get();
	return 0;
}

Program vypise nieco taketo, ty tam budes mat ine adresy objektov:

1. test:
construct 0025F895		//vytvori sa objekt
do something 0025F895	//zavola sa do_something()
destroy 0025F895		//znici sa objekt


2. test:
construct 0025F895		//vytvori sa objekt
destroy 0025F895		//znici sa objekt
do something 0025F895	//CHYBA zavola sa do_something() pre objekt ktory uz neexistuje, cize bug


3. test:
construct 0025F896		//vytvori sa objekt A (0025F896)
prekopiruje 0025F896 do premennej 0025F897   //vytvori sa kopia objektu A, nazvyme ju B (0025F897)
destroy 0025F896		//zmaze sa objekt A
do something 0025F897	//spusti sa do_something() pre objekt B	//objekt B je stale funkcny
destroy 0025F897		//znici sa objekt B	

 

Nahlásit jako SPAM
IP: 95.105.152.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Martin
~ Anonymní uživatel
1377 příspěvků
12. 8. 2014   #64
-
0
-

#63 vitamin
Mockrat dakujem....zajtra si to pomaly a postupne prestuduje a dam vediet ak by nieco.....

Nahlásit jako SPAM
IP: 77.48.69.–
mitti0
Newbie
13. 8. 2014   #65
-
0
-

#63 vitamin

#64 Martin
AHoj, takze uz tomu trosku viac rozumiem, len mi nie uje jasne tot:

Bod 2: const Test & test = fnc(Test());

Bod 3: Test test = fnc(Test());

Mam tieto otazky:

1. Vypis prveho: vytvori sa referencia na strukturu, ale kedze sa vola metoda struktury, dak je destruktor zavolany az po opusteni vykonavania veci v strukture.

Ale pri vypise druhom, ako navratovy typ dostaneme referenciu na strukturu, fnc(Test()), zavola sa bezparametricky konstruktor, a to je vsetko co sa v strukture malo vykonat, tym padom objekt zanikol, a uz sa iba do funkcie ma vratit referencia na objekt, ktory uz neexistuje.....

Ale tu tomu poriadne nerozumiem....

2. V bode 3 prijima funkcia ako parameter konstruktor Test() bez parametrov, tak ako je mozne, ze po spusteni programu este vlezie do kontruktora Test(const Test & a), je to z toho dovodu ze funckia ma navratovy typ referenciu na Test?

Nahlásit jako SPAM
IP: 159.51.236.–
mitti0
Newbie
14. 8. 2014   #66
-
0
-

#53 KIIV

#54 vitamin

nikto mi neodpovie???? ci to chapem dobre??

Nahlásit jako SPAM
IP: 159.51.236.–
KIIV+42
God of flame
14. 8. 2014   #67
-
0
-

U 1 uz je kompilator natolik chytrej, ze pochopi, co asi tak chces delat. Proste inicializuje test s tou novou instanci Test a jakmile skonci rozsah platnosti testu, tak to zlikviduje.

U 2 uz muzes vratit z fcn uplne neco jinyho. Takze rozsah platnosti Test() skonci zarovej s koncem fcn (ale mozna taky az po skonceni radku - aspon tak to vypada podle toho bodu 3).. (podobne, jako bys ten Test() vyrobil az uvnitr funkce - tam ale zrusi rovnou pri konci funkce)

U 3 je to jasny.. objekt zustal natolik dlouho, aby se mu nic nestalo a sel zkopirovat

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 156 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý