Mateusz Mirkowski

Mateusz Mirkowski Co-Founder @ Visent
Coders

Temat: Pomoc przy projekcie c++

Witam, potrzebuję pomocy przy projekcie z C++. Oczywiście chodzi o podpowiedzi, a nie zrobienie projektu. Projekt ma za zadanie umożliwić operacje na dużych integerach. To co mam na razie wygląda tak:

Duzaliczba.h

#ifndef Projekt_DuzaLiczba_h
#define Projekt_DuzaLiczba_h

#include <iostream>
#include <string.h>

using namespace std;

class DuzaLiczba{

char * m_wartosc;

public:
DuzaLiczba();
DuzaLiczba(int);
DuzaLiczba(char * liczba);

DuzaLiczba(const DuzaLiczba &);

~DuzaLiczba();

DuzaLiczba & operator = (int);
DuzaLiczba & operator = (DuzaLiczba &);
DuzaLiczba & operator = (char *);

DuzaLiczba & operator + (DuzaLiczba &);
DuzaLiczba & operator - (DuzaLiczba &);
DuzaLiczba & operator - ();
DuzaLiczba & operator * (DuzaLiczba &);
DuzaLiczba & operator / (DuzaLiczba &);

DuzaLiczba & operator += (DuzaLiczba &);
DuzaLiczba & operator += (int);
DuzaLiczba & operator -= (DuzaLiczba &);
DuzaLiczba & operator *= (DuzaLiczba &);
DuzaLiczba & operator /= (DuzaLiczba &);

friend bool operator == (DuzaLiczba &, DuzaLiczba &);
friend bool operator == (DuzaLiczba&, char *);
friend bool operator != (DuzaLiczba &, DuzaLiczba &);
friend bool operator != (DuzaLiczba &, char *);

friend bool operator >= (DuzaLiczba &, int);
friend bool operator < (DuzaLiczba &, char *);
friend bool operator ! (DuzaLiczba &);


friend ostream & operator << (ostream &, const DuzaLiczba &);
friend istream & operator >> (istream &, const DuzaLiczba &);

};


#endif



Duzaliczba.cpp


#include "DuzaLiczba.h"

DuzaLiczba::DuzaLiczba(){
m_wartosc = new char[1];
m_wartosc[0] = '\0';
}
DuzaLiczba::DuzaLiczba(int liczba){
m_wartosc = new char[(liczba) + 1];
sprintf(m_wartosc, "%d", liczba);
}

DuzaLiczba::DuzaLiczba(char * liczba) {
m_wartosc=strdup(liczba);
}

DuzaLiczba::DuzaLiczba(const DuzaLiczba & object)
{
m_wartosc = new char[strlen(object.m_wartosc) + 1];
strcpy(m_wartosc, object.m_wartosc);
}
DuzaLiczba::~DuzaLiczba()
{
delete[] m_wartosc;
m_wartosc = 0;





}



main.cpp


#include "DuzaLiczba.h"

using namespace std;

int main(){
// konstruktor bezargumentowy inicjalizuje obiekt wartością 0
DuzaLiczba l1;
// konstruktor z argumentem typu int inicjalizuje obiekt wartością stało-liczbową
DuzaLiczba l2(9999);
// konstruktor z argumentem typu char* inicjalizuje obiekt podaną wartością
DuzaLiczba l3("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
// konstruktor kopiujący głęboko
DuzaLiczba l4(l3);
// też konstruktor kopiujący głęboko
DuzaLiczba l5 = l4;
DuzaLiczba l6(-987654);

DuzaLiczba *l7 = new DuzaLiczba(“-999999999999999999999999999999”);

// Wszystkie obiekty od l1 do l6 są obiektami statycznymi,
// tzn. istnieją od początku do końca działania funkcji main
// natomiast obiekt wskazywany przez wskaźnik l7 jest
// obiektem dynamicznym, tzn. może być usunięty przez wywołanie
// operatora delete.


// przedefiniowany operator >>
cin >> l1;
// przedefiniowany operator <<
cout << l1 << l2 << l3 << l4 << l5 << l6 << *l7;

// usunięcie obiektu wskazywanego przez l7
delete l7;

// przedefiniowany operator =
l1 = l2;
// przedefiniowane operatory +-*/ dzielenie całkowite
l1 = l1 + l2 - l3 * l4 / l5;

// przedefiniowany operator +=
l1 += 23;
// przedefiniowany operator +=
l1 += l4;
// przedefiniowany operator -=
l2 -= l3;
// przedefiniowany operator *=
l3 *= l4;

// przedefiniowany operator ==
if(l4 == "23424")
// przedefiniowany operator /= dzielenie całkowite
l4 /= l5;

// przedefiniowany operator !=
if(l5 != l4) {
// przedefiniowany jednoargumentowy operator -
l5 = -l5;
cout << l5;
}

// przedefiniowany operator =
l2 = "1221";

DuzaLiczba silnia = 0;
// przedefiniowane operatory >= <
if(l2 >= 0 && l2 < "1223")
{
// przedefiniowany operator !
silnia = !l2;
cout << silnia ;
}

return 0;
}




DuzaLiczba *l7 = new DuzaLiczba(“-999999999999999999999999999999”);

W tej linijce mam błąd: expected expression. Wydaje mi się, że konsktruktory są dobrze zrobione. Jakieś pomysły?

konto usunięte

Temat: Pomoc przy projekcie c++

W książce "Implementing SSL/TLS Using Cryptography and PKI" (Joshua Davies) jest pokazany kod klasy 'huge', która implementuje dokładnie to o co Ci chodzi. (Do kupienia w Amazonie na Kindla)Piotr P. edytował(a) ten post dnia 16.01.13 o godzinie 12:19

konto usunięte

Temat: Pomoc przy projekcie c++

Witam,
pogooglaj może trochę, sporo jest na ten temat w sieci, to jest raczej standardowy temat. Ponadto: proponuję się przyjrzeć Pythonowi, któremu spore liczby nie są straszne i działania w nim wykonuje się klasycznie na większych liczbach, pzdr.Darek J. edytował(a) ten post dnia 16.01.13 o godzinie 12:58
Mateusz Mirkowski

Mateusz Mirkowski Co-Founder @ Visent
Coders

Temat: Pomoc przy projekcie c++

W googlach można znaleźć dużo, ale są to trochę inne projekty i trudno to przełożyć na mój. A czy ktoś może powiedzieć mi o co chodzi w tym błędzie expression expected, bo wydaje mi się, że póki co mam wszystko dobrze zrobione.

konto usunięte

Mateusz Mirkowski

Mateusz Mirkowski Co-Founder @ Visent
Coders

Temat: Pomoc przy projekcie c++

Jestem pewien, bo chcę zaliczyć przedmiot. :)

konto usunięte

Temat: Pomoc przy projekcie c++

1) Dodaj przed konstruktorem słowo "explicit" i zobacz czy to coś zmieni
http://weblogs.asp.net/kennykerr/archive/2004/08/31/Ex...

2) zmień nazwy zmiennych:
z: l1..l7
na: liczba1..liczba7

Ad.1
Możliwe że nie używasz konstruktora tego którego byś chciał.

Ad.2
l7 i 17 może wyglądać podobnie. To drugie zwykle nie będzie się kompilować tak jakby chciał tego twórca.
Mateusz Mirkowski

Mateusz Mirkowski Co-Founder @ Visent
Coders

Temat: Pomoc przy projekcie c++

Ok jeden problem rozwiązany, to był po prostu zły cudzysłów - literacki czy jakoś tak.
Tomasz Kaczanowski

Tomasz Kaczanowski Ot, programista

Temat: Pomoc przy projekcie c++

Mateusz Mirkowski:
Witam, potrzebuję pomocy przy projekcie z C++. Oczywiście chodzi o podpowiedzi, a nie zrobienie projektu. Projekt ma za zadanie umożliwić operacje na dużych integerach. To co mam na razie wygląda tak:
DuzaLiczba::DuzaLiczba(char * liczba) {
m_wartosc=strdup(liczba);
}
[..]
DuzaLiczba::~DuzaLiczba()
{
delete[] m_wartosc;
m_wartosc = 0;
}

ogólnie zwalnianie pamięci przydzielonej strdup
przez delete[] może być ryzykowne - nie mieszałbym allokatorów, gdyż nie w każdej bibliotece muszą być w podobny sposób implementowane...

konto usunięte

Temat: Pomoc przy projekcie c++

Tomasz Kaczanowski:
DuzaLiczba::~DuzaLiczba()
{
delete[] m_wartosc;
m_wartosc = 0;
}

ogólnie zwalnianie pamięci przydzielonej strdup
przez delete[] może być ryzykowne - nie mieszałbym allokatorów, gdyż nie w każdej bibliotece muszą być w podobny sposób implementowane...

Kończąc tę myśl lepiej zastosować free:


DuzaLiczba::~DuzaLiczba()
{
free(m_wartosc);
m_wartosc = 0;
}
Tomasz Kaczanowski

Tomasz Kaczanowski Ot, programista

Temat: Pomoc przy projekcie c++

Piotr L.:
Tomasz Kaczanowski:
DuzaLiczba::~DuzaLiczba()
{
delete[] m_wartosc;
m_wartosc = 0;
}

ogólnie zwalnianie pamięci przydzielonej strdup
przez delete[] może być ryzykowne - nie mieszałbym allokatorów, gdyż nie w każdej bibliotece muszą być w podobny sposób implementowane...

Kończąc tę myśl lepiej zastosować free:


DuzaLiczba::~DuzaLiczba()
{
free(m_wartosc);
m_wartosc = 0;
}

też nie do końca, gdyż są inne konstruktory przydzielające pamięć przez operator new... Ogólnie albo powinien się zdecydować na jeden sposób allokacji, albo zaznaczyć jak zwalniać pamięć.

konto usunięte

Temat: Pomoc przy projekcie c++

Tomasz Kaczanowski:
też nie do końca, gdyż są inne konstruktory przydzielające pamięć przez operator new... Ogólnie albo powinien się zdecydować na jeden sposób allokacji, albo zaznaczyć jak zwalniać pamięć.

Biorąc pod uwagę że to klasa to pewnie warto wszystko zmienić na C++ (new/delete, std::string).
Mateusz Mirkowski

Mateusz Mirkowski Co-Founder @ Visent
Coders

Temat: Pomoc przy projekcie c++

Dzięki za pomoc i za zainteresowanie, tylko teraz w końcu nie wiem co mam zmienić xD Czy zmienić delete na free czy nie?

konto usunięte

Temat: Pomoc przy projekcie c++

Mateusz Mirkowski:
Dzięki za pomoc i za zainteresowanie, tylko teraz w końcu nie wiem co mam zmienić xD Czy zmienić delete na free czy nie?

Zmień wszystko na C++ way:


class DuzaLiczba{

std::string m_wartosc;
...
};

DuzaLiczba::DuzaLiczba(){
}

DuzaLiczba::DuzaLiczba(int liczba){
std::stringstream out;
out << liczba;
m_wartosc = out.str();
}

DuzaLiczba::DuzaLiczba(char * liczba) {
m_wartosc.swap(std::string(liczba));
}

DuzaLiczba::DuzaLiczba(const DuzaLiczba & object)
{
m_wartosc = object.m_wartosc;
}
DuzaLiczba::~DuzaLiczba()
{
}
Mateusz Mirkowski

Mateusz Mirkowski Co-Founder @ Visent
Coders

Temat: Pomoc przy projekcie c++

Tylko, że ja to muszę zrobić na char'ach. ;)
Tomasz Kaczanowski

Tomasz Kaczanowski Ot, programista

Temat: Pomoc przy projekcie c++

Mateusz Mirkowski:
Tylko, że ja to muszę zrobić na char'ach. ;)

to zrób. Czy będziesz stosował malloc/free, czy new/delete większego znaczenia nie ma, ważne abyś stosował je właściwie. Tak więc nie miwszać allokatorów. Dodatkowo taka podpowiedz - widziałem, że domylny konstruktor allokuje 1 bajt - bez sensu. Powinien allokować najbardziej optymalną liczbę bajtów, tak aby z dużym prawdopodobieństwem nie trzeba było reallokować pamięci przy najmniejszej operacji.

konto usunięte

Temat: Pomoc przy projekcie c++

Tomasz Kaczanowski:
Mateusz Mirkowski:
Tylko, że ja to muszę zrobić na char'ach. ;)

to zrób. Czy będziesz stosował malloc/free, czy new/delete większego znaczenia nie ma, ważne abyś stosował je właściwie. Tak więc nie miwszać allokatorów. Dodatkowo taka podpowiedz - widziałem, że domylny konstruktor allokuje 1 bajt - bez sensu. Powinien allokować najbardziej optymalną liczbę bajtów, tak aby z dużym prawdopodobieństwem nie trzeba było reallokować pamięci przy najmniejszej operacji.

Ewentualnie może nie alokować nic (=NULL).
Dzięki temu niewykorzystane zmienne (ze względu na ścieżkę przetwarzania lub tagowanie w TMP) nie będą obciążać pamięci.

Przydatne przy scenariuszu:


DuzaLiczba a,b;
//...
a = 122;
b = a + 2;


Przy tym typie docelowo zmienna, jeśli będzie miała być wypełniona to raczej długim ciągiem.
W związku z tym jeśli w niej domyślnie alokować taki ciąg to ma to znaczenie.
Karol R.

Karol R. Projektant /
Programista

Temat: Pomoc przy projekcie c++

To c++ więc new/delete, a nie malloc/free i cout, a nie printf. Pomijając to nikt nie zwrócił uwagi na operatory(oznaczanie niezmienności słowem const to wcale nie fanaberia):

//operator +, -, *, / powinien być zwracany przez wartość -> x = (a+b) * c;
DuzaLiczba operator+ (const DuzaLiczba& right)const;

//operatory porównań nie muszą być funkcjami zaprzyjaźnionymi
bool operator== (const DuzaLiczba& right)const;Karol Redosz edytował(a) ten post dnia 29.01.13 o godzinie 09:06
Tomasz Kaczanowski

Tomasz Kaczanowski Ot, programista

Temat: Pomoc przy projekcie c++

Karol Redosz:
To c++ więc new/delete, a nie malloc/free i cout, a nie printf.

Tu do końca zgodzić sie nie można. Pisząc w C++ nie ma obowiązku korzystania z biblioteki standardowej, więc to już zależy od kontekstu. Oczywiście, jeśli nie ma jakiś przeciwskazań natury technicznej, to oczywiście jest to wygodniejsze i nierzadko bardziej optymalne, ale nie zawsze tak jest.
Karol R.

Karol R. Projektant /
Programista

Temat: Pomoc przy projekcie c++

Tomasz Kaczanowski:
Karol Redosz:
To c++ więc new/delete, a nie malloc/free i cout, a nie printf.

Tu do końca zgodzić sie nie można. Pisząc w C++ nie ma obowiązku korzystania z biblioteki standardowej, więc to już zależy od kontekstu. Oczywiście, jeśli nie ma jakiś przeciwskazań natury technicznej, to oczywiście jest to wygodniejsze i nierzadko bardziej optymalne, ale nie zawsze tak jest.

Z postów powyżej wynika, że to projekt na zaliczenie przedmiotu - w dodatku b. prosty, stąd moja wypowiedź. Brak tych const'ów w operatorach to właściwie też nie jest błąd ale w przyszłości do takich może prowadzić. Jeśli natomiast rozmawiamy o problemach rzeczywistych to przecież możemy korzystać ze sprytnych wskaźników i zapomnieć o problemie alokowania i zwalniania pamięci.

Następna dyskusja:

Pomoc przy C




Wyślij zaproszenie do