Cześć, przerabiam w ramach ćwiczenia klasę string:
Mam problem z String operator+(const String & st1,const String & st2); . Bez dodanego konstruktora przenoszącego działa przeciążenie operatora poprawnie, natomiast z konstruktorem następuje błąd. Szczególnie nie rozumiem w jakim momencie przenoszenie psuje operator+, ani jak to się dzieje :(
Invalid address specified to RtlValidateHeap coś ze zwolnieniem się dzieje...
Header.h
#ifndef HEADER_H_
#define HEADER_H_
#include <iostream>
#include <string.h>
#include <cctype>
using std::ostream;
using std::istream;
class String
{
private:
char *data; // wskaźnik ciągu
int len; // długość ciągu
public:
String(); // konstruktor domyślny
String(const char * s); // konstruktor kopiujący
String(const String & st); // konstruktor kopiujący
String(String&& rhs); // konstruktor przenoszący
~String(); // destruktor
String & operator=(const String & st);
String & operator=(const char * s);
friend ostream & operator<<(ostream & os, const String & st);
friend istream & operator>>(istream & is, String & st);
auto getData() const { return data; }
auto setData(const String & st1, const String & st2);
auto getLength() const { return len; }
auto setLenght(const String & st1, const String & st2) { len = st1.len + st2.len; }
};
String operator+(const String & st1,const String & st2);
#endif // !HEADER_H_
Def.cpp
#include <cstring>
#include "header.h"
using std::cin;
using std::cout;
String::String(const char * s): // konstruje obiekt String z ciągu C
len(std::strlen(s)) // ustawienie długości ciągu
{
data = new char[len+1]; // przydział pamięci
strcpy_s(data,len+1 ,s); // inicjalizacja wskaźnika ciągu
}
String::String() // konstruktor domyślny
{
len = 1;
data = new char[1];
data[0] = '\0'; // domyślny ciąg obiektów klasy
}
String::String(const String & st):
len(st.getLength()) // ta sama długość ciągu
{
data = new char[len + 1]; // przydział pamięci
strcpy_s(data, len + 1, st.getData()); // skopiowanie ciągu
}
String::String(String&& rhs):
len(std::move(rhs.len)),
data(std::move(rhs.data))
{
}
String::~String() // destruktor
{
delete[] data;
}
// przypisywanie obiektu klasy String do innego obiektu tej klasy
String & String::operator=(const String & st)
{
if (this == &st)
return *this;
delete[] data;
len = st.len;
data = new char[len + 1];
strcpy_s(data, len + 1, st.getData());
return *this;
}
// przypisywanie ciągu C do obiektu klasy String
String & String::operator=(const char * s)
{
delete[] data;
len = std::strlen(s);
data = new char[len + 1];
strcpy_s(data, len + 1, s);
return *this;
}
// wyprowadzenie ciągu na wyjście
ostream & operator<<(ostream & os, const String & st)
{
os << st.data;
return os;
}
// wczytywanie ciągu z wejścia (uproszczone)
istream & operator>>(istream & is, String & st)
{
char temp[String::CINLIM];
is.get(temp, String::CINLIM);
if (is)
st = temp;
while (is && is.get() != '\n')
continue;
return is;
}
auto String::setData(const String & st1, const String & st2)
{
data = new char[getLength() + 1];
strcpy_s(data, getLength() + 1, st1.getData()); //tutaj wywala wyjątek
strcat_s(data, getLength() + 1, st2.getData());
}
String operator+(const String & st1, const String & st2)
{
String temp;
temp.setLenght(st1, st2);
temp.setData(st1, st2);
return temp;
}
main.cpp
#include <iostream>
#include "header.h"
int main()
{
using std::cout;
using std::cin;
using std::endl;
const char* src = "Make the test";
cout << endl<<"String(const char * s); "<<endl;
String test1=String(src);
cout << test1.getData()<<endl;
cout << endl<<"String(const String & st);"<<endl;
String test2(test1);
cout << test2.getData()<<endl;
cout << endl << "const String operator+(const String & st1, const String & st2);" << endl;
String test3= "Let's do it!!! " + test1 + test2 + " Make it!!!";
cout << test3.getData() << endl;
cout << endl << "String(String&& rhs);" << endl;
String test4(std::move(test1));
cout << test4.getData() << endl;
system("pause");
return 0;
}
Byłbym bardzo wdzięczny za wszelkie uwagi ;)