Objektumok memóriakezelése
Dobra Gábor · 2022.03.03.
Objektumok memóriakezelése
A videó a jegyzet 3. fejezetéhez és 4. fejezetéhez tartozik.
char* teljes_nev(char const* vezeteknev, char const* keresztnev) {
if (vezeteknev == NULL || keresztnev == NULL)
return NULL; // hibás paraméterek
int h1 = strlen(vezeteknev);
int h2 = strlen(keresztnev);
int ujmeret = h1 + 1 + h2 + 1; // szóköz + lezáró nulla
char* eredmeny = (char*)malloc(ujmeret * sizeof(char));
if (eredmeny == NULL) // hiba történt
return NULL;
strcpy(eredmeny, vezeteknev);
strcat(eredmeny, " ");
strcat(eredmeny, keresztnev);
return eredmeny;
}
#include <iostream>
#include "String.h"
int main() {
String s1, s2;
std::cin >> s1 >> s2; // lehessen beolvasni...
String s3 = s1 + s2; // ...összefűzni...
std::cout << "s3 = " << s3 << std::endl; // ...kiírni...
s2 += s1; // ...és a végéhez hozzáfűzni
std::cout << "s2 = " << s2 << std::endl;
return 0;
}
#include <iostream>
class String {
char str[256]; // nullával lezárt
public:
String(char const* s = "");
String operator+(String const& rhs) const;
String& operator+=(String const& rhs);
String& operator+=(char rhs);
int length() const;
char const* c_str() const;
};
std::ostream& operator<<(std::ostream& os, String const& rhs);
std::istream& operator>>(std::istream& is, String& rhs);
int main() {
String s1, s2;
std::cin >> s1 >> s2;
std::cout << "s1 + s2 = " << s1 + s2 << std::endl;
s2 += s1;
std::cout << "s2 + s1 = " << s2 << std::endl;
return 0;
}
Megoldás
#include <iostream>
class String {
char str[256]; // nullával lezárt
public:
String(char const* s = "") {
strcpy(str, s);
}
String operator+(String const& rhs) const {
String result = *this;
result += rhs;
return result;
}
String& operator+=(String const& rhs) {
strcat(str, rhs.str);
return *this;
}
String& operator+=(char rhs) {
int len = strlen(str);
str[len] = rhs;
str[len+1] = '\0';
return *this;
}
int length() const {
return strlen(str);
}
char const* c_str() const {
return str;
}
};
std::ostream& operator<<(std::ostream& os, String const& rhs) {
os << rhs.c_str();
return os;
}
std::istream& operator>>(std::istream& is, String& rhs) {
char c;
String uj;
while(is.get(c) && !isspace(c))
uj += c;
rhs = uj;
return is;
}
class String {
char str[256];
public:
/* ... */
char& operator[](int i) {
if (i < 0 || i >= strlen(str))
throw std::out_of_range("String: túlindexelés");
return str[i];
}
char const& operator[](int i) const { // két const!
if (i < 0 || i >= strlen(str))
throw std::out_of_range("String: túlindexelés");
return str[i];
}
};
- sztring: dinamikus karaktertömb
- dinamikus tömb: pointer + méret
- érdemes továbbra is nullával lezárni
- méretbe ne számoljuk bele a lezáró nullát
size_t
: tömb méretét tárolni képes valamilyen unsigned típus
class String {
size_t size;
char* str;
public:
String();
String(char const* s);
~String(); // amennyi a new, annyi a delete
/* ... */
};
Írjuk meg a konstruktort és a destruktorokat!
#include <iostream>
class String {
size_t size;
char* str;
public:
String();
String(char const* s);
~String();
String operator+(String const& rhs) const;
String& operator+=(String const& rhs);
String& operator+=(char rhs);
size_t length() const {
return size;
}
char const* c_str() const {
return str;
}
};
std::ostream& operator<<(std::ostream& os, String const& rhs) {
os << rhs.c_str();
return os;
}
std::istream& operator>>(std::istream& is, String& rhs) {
char c;
String uj;
while (is.get(c) && !isspace(c))
uj += c;
rhs = uj;
return is;
}
int main() {
String s1, s2;
std::cin >> s1 >> s2;
std::cout << "s1 + s2 = " << s1 + s2 << std::endl;
s2 += s1;
std::cout << "s2 + s1 = " << s2 << std::endl;
return 0;
}
Megoldás
#include <iostream>
class String {
char str[256]; // nullával lezárt
public:
String(char const* s = "") {
strcpy(str, s);
}
String operator+(String const& rhs) const {
String result = *this;
result += rhs;
return result;
}
String& operator+=(String const& rhs) {
strcat(str, rhs.str);
return *this;
}
String& operator+=(char rhs) {
int len = strlen(str);
str[len] = rhs;
str[len+1] = '\0';
return *this;
}
int length() const {
return strlen(str);
}
char const* c_str() const {
return str;
}
};
std::ostream& operator<<(std::ostream& os, String const& rhs) {
os << rhs.c_str();
return os;
}
std::istream& operator>>(std::istream& is, String& rhs) {
char c;
String uj;
while(is.get(c) && !isspace(c))
uj += c;
rhs = uj;
return is;
}
Írjuk meg a másoló konstruktort!
#include <iostream>
class String {
size_t size;
char* str;
public:
String() {
size = 0;
str = new char[1];
str[0] = '\0';
}
String(char const* s) {
size = strlen(s);
str = new char[size + 1];
strcpy(str, s);
}
~String() {
delete[] str;
}
size_t length() const {
return size;
}
char const* c_str() const {
return str;
}
};
int main() {
String s1, s2;
std::cin >> s1 >> s2;
String a = "hello";
String b = a;
s2 = b;
std::cout << "s1 + s2 = " << s1 + s2 << std::endl;
s2 += s1;
std::cout << "s2 + s1 = " << s2 << std::endl;
return 0;
}
Megoldás
#include <iostream>
class String {
/* ... */
String(String const& other) {
size = other.size;
str = new char[size + 1];
strcpy(str, other.str);
}
};
Írjuk meg az értékadó operátort!
#include <iostream>
class String {
size_t size;
char* str;
public:
String() {
size = 0;
str = new char[1];
str[0] = '\0';
}
String(char const* s) {
size = strlen(s);
str = new char[size + 1];
strcpy(str, s);
}
String(String const& other) {
size = other.size;
str = new char[size + 1];
strcpy(str, other.str);
}
~String() {
delete[] str;
}
size_t length() const {
return size;
}
char const* c_str() const {
return str;
}
};
int main() {
String s1, s2;
std::cin >> s1 >> s2;
String a = "hello";
String b = "assign";
b = a;
std::cout << "s1 + s2 = " << s1 + s2 << std::endl;
s2 += s1;
std::cout << "s2 + s1 = " << s2 << std::endl;
return 0;
}
Megoldás
#include <iostream>
class String {
/* ... */
String& operator=(String const& other) {
if (this != &other) {
size = other.size;
str = new char[size + 1];
strcpy(str, other.str);
}
return *this;
}
};
...de lehetőleg egyiket se kelljen megírnunk:
char*
helyett használjunk sztring osztálytString
helyett használjunkstd::string
-et!
- Single Responsibility Principle
struct Vonatjegy {
std::string indulo_allomas;
std::string vegallomas;
};
- ennek a struct-nak nem kell egyiket se megírni
- a fordító által generált copy ctor,
operator=
jó lesz
class Vonatjegy {
std::string indulo_allomas;
std::string vegallomas;
public:
Vonatjegy(std::string const& honnan, std::string const& hova){
// a konstruktor törzse előtt default konsturktorok
indulo_allomas = honnan; // értékadás
vegallomas = hova; // értékadás
}
};
Megoldás
class Vonatjegy {
std::string indulo_allomas;
std::string vegallomas;
public:
Vonatjegy(std::string const& honnan, std::string const& hova)
: indulo_allomas(honnan), vegallomas(hova) {
}
};