How to write the function of appropriating of objects of class - c++

I need to assign one object to another object by overloading the "=" operator. Wrote code, but it doesn`t work. What could be the problem?
CString operator =(const CString& obj) {
CString temp;
temp.c = obj.c;
temp.length = obj.length;
return temp;
}
Full code:
#include <iostream>
using namespace std;
class CString {
private:
char* c;
int length;
public:
CString() {
length = 0;
c = new char[1];
*c = 0;
}
CString(const char* s) {
length = strlen(s);
c = new char[length + 1];
for (int i = 0; i < length; i++) { c[i] = s[i]; }
c[length] = '\0';
}
CString(int leng, char* payload) {
length = leng;
c = payload;
}
~CString() {
delete[] c;
}
CString operator +(const CString& b) {
int newlength = length + b.length;
char* newstr = new char[newlength + 1];
strcpy(newstr, c);
strcpy(newstr + length, b.c);
return CString(newlength, newstr);
}
void Show(void) { cout << c << endl; }
CString operator =(const CString& obj) {
CString temp;
temp.c = obj.c;
temp.length = obj.length;
return temp;
}
};
int main() {
CString a("First, ");
CString b("Second.");
a = c;
return 0;
}

First comment: as long as you specify the non-trivial destructor, and - even more imortant - the copy assignment, you need to specify the copy constructor as well.
Next, the copy operator shall return the reference to *this: this allows you to employ chaining like that: 'a = b = c;'
The copy-assignment may look like that:
CString& operator =(const CString& obj) {
delete[] c;
length = obj.length;
c = new char[length + 1];
for (int i = 0; i <= length; i++) { c[i] = obj.c[i]; }
return *this;
}
However, taking my first comment into consideration, you may implement the copying just once:
CString(const CString& obj) {
length = obj.length;
c = new char[length + 1];
for (int i = 0; i <= length; i++) { c[i] = obj.c[i]; }
}
CString& operator =(const CString& obj) {
CString tmp(obj)
swap(length, tmp.length);
swap(c, tmp.c);
return *this;
}
In addition your constructor CString(int leng, char* payload) looks suspicious. Do you realize that the c-string has to be allocated with new (and will be deleted in destructor)?

Related

The following code has some issue in implementation of overloaded minus operator

#include<iostream>
#include<cstring>
#include<utility>
class String {
// think about the private data members...
char* input;
int length;
public:
// provide definitions of following functions
String() {
input = NULL;
length = 0;
}
// default constructor
String(const char* str) {
int size = strlen(str);
char* string = new char[size];
for (int i = 0; i < size; i++) {
string[i] = str[i];
}
input = string;
length = size;
}
// initializes the string with constant c-string
String(const String& str) {
input = str.input;
length = str.length;
}
// copy constructor to initialize the string from the existing string
String(int x) {
length = x;
input = new char[length];
} // initializes a string of predefined size
char& operator[](int i) {
return *(input + i);
}
// returns the character at index [x]
const char operator[](int i) const {
return *(input + i);
}
// Assignment Operators
void swap(String& other)
{
std::swap(input, other.input);
std::swap(length, other.length);
}
String& operator=(char ch)
{
String newstr(1);
newstr[0] = ch;
newstr.swap(*this);
return *this;
}
String& operator=(const char* str)
{
String(str).swap(*this);
return *this;
}
String& operator=(const String& str)
{
if (this != &str)
String(str).swap(*this);
return *this;
}
String& operator=(String&& str)
{
String(std::move(str)).swap(*this);
return *this;
}
String& operator-(const String& substr) //remove the substr from the string
{
char* fd;
int p = substr.length;
fd = strstr(input, substr.input);
if (fd)
{
int newsize = length - p;
String newstr(newsize);
int n = fd - input;
for (int i = 0; i < n; i++)
newstr.input[i] = input[i];
int m = length - p - n;
for (int i = n; i <= n + m; i++)
newstr.input[i] = input[i + p];
}
return *this;
}
String& operator-(const string& substr) // remove the substr from the string
{
char* fd;
int p = substr.size();
fd = strstr(input, substr.c_str());
if (fd)
{
int newsize = length - p;
String newstr(newsize);
int n = fd - input;
for (int i = 0; i < n; i++)
newstr.input[i] = input[i];
int m = length - p - n;
for (int i = n; i <= n + m; i++)
newstr.input[i] = input[i + p];
delete[]input;
length = newsize;
input = newstr.input;
}
return *this;
}
int main()
{
String s1("ababacc");
String s2("aba");
String string2("cc");;
s2 = s1 - s2;
cout<< s2[0];
cout<< s2[1];
cout<<s2[2];
s2 = s2 - string2;
cout<< s2[0];
cout<< s2[1];
}
I have overloaded the minus operator two times i.e String& operator-(const String& substr) and String& operator-(const string& substr). The cout statements in main functions are not giving the actual output. cout<<s2[0] is supposed to give 'b' in output. cout<< s2[1]; is supposed to give 'a' in output and cout<<s2[2] is supposed to give 'c' in output. But when I run this code I am not getting these actual values. What am I doing wrong?

Array getting wrong amount of spaces

So I've been trying to write string class for learning purposes, and when I tried to overload the + operator I got the strangest problem: The array I've been trying to crate had 4 extra spaces, no matter what amount I tried to create it with (Also the entire thing crashed horribly). So for example, when I wrote:
newStr.length = this->length + other.length;
newStr.str = new char[newStr.length+1];
newStr.str kept having 4 more spaces than this->length + other.length + 1, and when I just left it at newStr.str = new char[1], the array still have been created with 5 cells for some reason. I've tried to write the entire class without ever creating "int length" but that didn't work, nor did any my attempts to isolate the array creation from class(It works normally when not in class and not working with these specific class objects so it's not some visual studio bug). I've tried everything I could think of, though I'm new at this and most likely missed something. Could anybody please help me? Here's the entire code for reference, it's not that long:
#include <iostream>
#define DEBUG
using namespace std;
class MyString
{
private:
char* str;
int length;
public:
MyString()
{
str = nullptr;
length = 0;
}
MyString(const char *str)
{
length = strlen(str);
this->str = new char[length + 1];
for (int i = 0; i < length; i++)
{
this->str[i] = str[i];
}
this->str[length] = '\0';
}
~MyString()
{
delete[] str;
}
MyString& operator =(const MyString& other)
{
if (this->str != nullptr) delete[] str;
length = other.length;
this->str = new char[length + 1];
for (int i = 0; i < length; i++)
{
this->str[i] = other.str[i];
}
this->str[length] = '\0';
return *this;
}
MyString operator +(const MyString& other)
{
MyString newStr;
newStr.length = this->length + other.length;
newStr.str = new char[newStr.length+1];
for (int i = 0; i < this->length; i++)
{
newStr.str[i] = this->str[i];
}
for (int i = this->length; i < newStr.length; i++)
{
newStr.str[i] = other.str[i-strlen(this->str)];
}
newStr.str[newStr.length] = '\0';
return newStr;
}
void Print()
{
cout << str;
}
};
int main()
{
MyString a("TESTY");
MyString b("WUBBA");
a = a + b;
a.Print();
return 0;
}

How to overload operator + in c++ to be able whrite c_str = "smth" + c_str;

I would like to make a CMyString class. It represents an object with contains char array. I need to overload opereators to be able to sum these objects. Here is this class
CMyString::CMyString()
{
i_length = 0;
n_string = new char[1];
n_string[0] = '\0';
}
CMyString::CMyString(const char *cChar)
{
i_length = iSourceLength(cChar);
n_string = new char[i_length];
for (int ii = 0; ii < i_length; ii++)
n_string[ii] = cChar[ii];
}
CMyString::CMyString(const CMyString &pcOther)
{
i_length = pcOther.i_length;
n_string = new char[i_length];
for (int ii = 0; ii < i_length; ii++)
n_string[ii] = pcOther.n_string[ii];
}
void CMyString::vCopyFrom(const CMyString &pcOther)
{
for (int ii = 0; ii < i_length; ii++)
n_string[ii] = pcOther.n_string[ii];
}
bool CMyString::bResize(int newSize)
{
if (newSize <= 0)
return false;
delete(this->n_string);
this->n_string = new char[newSize];
i_length = newSize;
return true;
}
//bool CMyString::bResize(int newSize)
int CMyString::iSourceLength(const char *cChar)
{
int i_source_length = 0;
while (cChar[i_source_length] != '\0')
i_source_length++;
return i_source_length;
}
//int CMyString::iSourceLength(const char *cChar)
CMyString& CMyString:: operator= (const CMyString& pcOther)
{
if (this != &pcOther) // guard against a = a;
{
delete[] n_string; // release old memory & then allocate new memory
i_length = pcOther.i_length;
n_string = new char[i_length];
vCopyFrom(pcOther);
}
return *this; // return a reference to itself to allow a = b = c;
}
//CMyString& CMyString:: operator= (const CMyString& pcOther)
void CMyString:: operator= (const char *cChar)
{
if (i_length != 0)
delete[] n_string;
i_length = iSourceLength(cChar); // count the length of init value
n_string = new char[i_length]; // allocate storage
for (int ii = 0; ii < i_length; ii++) // copy init value into storage
n_string[ii] = cChar[ii];
}
//void CMyString:: operator= (const char *cChar)
CMyString& CMyString:: operator+ (const CMyString& pcOther)
{
CMyString *c_res = new CMyString;
if (i_length == 0 && pcOther.i_length == 0)
{
c_res->i_length = 0;
c_res->n_string = NULL;
}
c_res->i_length = i_length + pcOther.i_length;
c_res->n_string = new char[c_res->i_length];
int ii;
for (ii = 0; ii < i_length; ii++)
c_res->n_string[ii] = n_string[ii];
for (int ij = 0; ij < pcOther.i_length; ij++, ii++)
c_res->n_string[ii] = pcOther.n_string[ij];
return *c_res;
}
CMyString::operator char*()
{
return n_string;
}
//CMyString& CMyString:: operator+ (const CMyString& pcOther)
CMyString::operator char*() const
{
return n_string;
}
What should i do to be able to write c_str = "smth" + c_str?? Compiler underlines me this plus. No operator "+" matches this operands. Operands types are: const char[4] and CMyString?
For more information you can visit this website.
class CMyString
{
private:
string str;
public:
CMyString(string _str) { str = _str; }
friend CMyString operator+(string value, CMyString Str);
string GetStr() {return str;};
};
CMyString operator+(string value, CMyString Str)
{
return CMyString(value + Str.str);
}
int main()
{
CMyString test("Test");
test = "smth" + test;
cout << test.GetStr();
return 0;
}

I don't know why it occurs heap corruption(about memory allocation problem)

it's course's one of project and its goal is to make fully-worked MyString Class. Until made destructor method, it was worked well. but in main.cpp, when i tried to use these method i made, it occurs heap corruption. i thought the problem comes up from order of calling destructor but i couldn't figure out where it occurred.
try to check allocated memory(reverse called order)
processing without destructor method(it works)
main.cpp
void main() {
MyString a = MyString("HELLOMYNAMEIS");
char ab[10] = "thisiskrw";
MyString c = ab;
a = a + c;
cout << a;
}
MyString.cpp
MyString::~MyString() {
delete[] str_;
}
MyString operator+(const MyString& lhs, const MyString& rhs) {
MyString a(lhs);
MyString b(rhs);
a += b;
cout << a;
return a;
}
MyString& MyString::operator+=(const MyString& str) {
int i = 0;
if (this->capacity() < (this->length_ + str.length_)) {
char* temp = new char[this->length_ + str.length_+1];
memset(temp, '\0', this->length_+str.length_+1);
strcpy(temp, this->str_);
for (int i = 0; i < str.length_; i++) {
temp[(this->length_) + i] = str.str_[i];
}
temp[this->length_ + str.length_] = '\0';
strcpy(this->str_,temp);
this->length_ = this->length_ + str.length_;
delete[] temp;
}
else {
for (int i = 0; i < str.length_; i++) {
this->str_[(this->length_) + i] = str.str_[i];
}
this->length_ = this->length_ + str.length_;
}
return *this;
}
it will print string inside MyString object.
You forgot to write this->str_ = temp; anywhere. You just try to write the longer string into the shorter space.
strcpy(this->str_,temp);
this->length_ = this->length_ + str.length_;
delete[] temp;
Should be
delete [] this->str_;
this->str_ = temp;

Pointer and orphan memory management

Firstly here is my code:
header:
#pragma once
#include <iostream>
using namespace std;
class CString
{
private://Main attribute
char* str;
private:// Aux attribute
int len;
public:
//constructor and destructor
CString(char* x);
CString() { len = 0; str = NULL; }
~CString()
{
if (NULL != str)
delete[] str;
str = NULL;
}
//some operator
CString operator+(CString x);
CString operator+(char* x);
void operator=(CString x);
//operator() is to extract a part of other CString object
CString operator()(unsigned pos, unsigned c_len);
//operator[] return position of CString::str[pos]
char& operator[](unsigned pos);
//Ostream output
friend ostream& operator<<(ostream& os, CString x);
};
//to do char+CString
CString operator+(char* a, CString x);
header cpp code:
#include "CString.h"
CString::CString(char * x)
{
len = 0;
while(x[len])
len++;
str = new char[len];
for (int i = 0;i < len;i++)
str[i] = x[i];
if (str[len - 1] != '\0')
{
len++;
char* tmp;
tmp = new char[len];
for (int i = 0;i < len - 1;i++)
tmp[i] = str[i];
delete[]str;
str = tmp;
tmp = NULL;
str[len - 1] = '\0';
}
}
CString CString::operator+(CString x)
{
CString* result;
result = new CString;
result->len = this->len + x.len - 1;
result.str=new char[result.len];
for (int i = 0; i < this->len - 1;i++)
{
result->str[i] = this->str[i];
}
for (int i = 0, j = this->len - 1;i < x.len;i++, j++)
{
result->str[j] = x.str[i];
}
return *result;
}
CString CString::operator+(char * x)
{
return CString(*this+CString(x));
}
void CString::operator=(CString x)
{
str = new char[x.len];
for (int i = 0; i < x.len;i++)
str[i] = x.str[i];
len = x.len;
}
CString CString::operator()(unsigned pos, unsigned c_len)
{
CString* result;
result = new CString;
result->len = c_len;
result.str=new char[c_len];
for (int i = pos;i < pos + c_len;i++)
result->str[i - pos] = str[i];
return *result;
}
char& CString::operator[](unsigned pos)
{
if (pos < len - 1)
{
char* ptr;
ptr = this->str + pos;
return *ptr;
}
else
{
int o_len = len;
len = pos + 2;
char* tmp;
tmp = new char[len];
for (int i = 0;i < o_len;i++)
{
tmp[i] = str[i];
}
tmp[len - 1] = '\0';
delete[]str;
str = tmp;
tmp = NULL;
return *(str + pos);
}
}
ostream & operator<<(ostream & os, CString x)
{
os << x.str;
return os;
}
CString operator+(char * a, CString x)
{
return CString(CString(a) + x);
}
main:
CString a("string 1"), b = "Initialize " + a;
b[15] = '2'; cout << a + " - " + b << endl;
CString c = a + b;
cout << "String extracted from string \"" << c
<< "\" from position 3 with length of 6 is: \""
<< c(3, 6) << "\"" << endl;
Problem:
When I try to compile this program, there is no error, but still operator+(CString), operator(), and destructor seem to malfunction.
When I debug this program, my program triggered a breakpoint some where at line CString a("String 1"), b = "initilize " + a; I have no idea why. I am do not know if there is any problem for the rest of the program because I always get stuck at that line. SO if somebody can find out any other problem, please tell me, that will save me another day.
Btw, I just wonder at operator+(CString) and operator(), I have create a pointer then I use new and then I return that pointer, so that I have no change to delete that pointer, will it leave me an orphan memory? Since I have read another question about return a class object, I found out that if I use CString result and then return result, result would be destroyed before return. SO is there any better way to do that?
Summary:
1.My program triggered a breakpoint some where in the second line of main().
2.How to properly return a class object?
P.S: I am really bad at communicating and just have 1 year period of C/C++ learning. So if I have type some thing could give you a cancer, please forgive me.
Sincerely thank you.