c++ unable to change members of array - c++

i am really stuck on following problem:
2 classes:
class Article
{
char* _code;
char* _name;
double _price;
int _quantity;
public:
Article(char* code = "code", char * name = "name", double price = 0){
setCode(code);
setName(name);
_price = price;
_quantity = 0;
}
Article(Article & a){
setCode(a._code);
setName(a._name);
_price = a._price;
_quantity = a._quantity;
}
~Article(){
delete[] _code; _code = nullptr;
delete[] _name; _name = nullptr;
}
/*******SETTERS********/
void setCode(char* code){
int vel = strlen(code);
_code = new char[vel + 1];
strncpy_s(_code, vel + 1, code, _TRUNCATE);
}
void setName(char* name){
int vel = strlen(name);
_name = new char[vel + 1];
strncpy_s(_name, vel + 1, name, _TRUNCATE);
}
void setPrice(double c){ _price = c; }
/*******GETTERS********/
int getquantity(){ return _quantity; }
double getprice(){ return _price; }
//operator =
Article operator = (Article& a){
setName(a._name);
setCode(a._code);
_price = a._price;
_quantity = a._quantity;
return *this;
}
//operator-= decrease qnty for passed value.
bool operator-=(int v){
if (_quantity > v)
{
_quantity = _quantity - v;
return true;
}
cout << "Operacija nije moguca, stanje je manje nego vrijednsot za koju se umanjuje";
return false;
}
// operator ++ increase Qnty for 1.
Article operator++(int){
//Article A(_code, _name, _price);
this->_quantity++;
return *this;
}
//Preklopiti operator -- decrease value for 1.
Article operator--(){
if (_quantity >= 1)
{
_quantity--;
}
return *this;
}
//compare articles based on code.
bool operator==(Article & a){
if (strncmp(_code, a._code, strlen(_code)) == 0)
{
return true;
}
return false;
}
//operator <<
friend ostream & operator<<(ostream & COUT, Article & a);
};
ostream & operator<<(ostream & COUT, Article & a){
COUT << "code: " << a._code << endl << "name: " << a._name << endl << "price: " << a._price << ", Qnty: " << a._quantity << "\n ----------------------- \n\n";
return COUT;
}
class Item
{
Article _Article;
int* _quantity;
public:
Item(Article & a, int quantity) :_Article(a){
_quantity = new int(quantity);
}
Item() :_Article("StavkaR", "nameR", 0){
_quantity = new int(0);
}
Item(Item& s) :_Article(s._Article){
_quantity = new int(*s._quantity);
}
~Item(){
delete _quantity; _quantity = nullptr;
}
int getquantity(){ return *_quantity; }
void setquantity(int v) { *_quantity += v; }
Article getArticle() { return _Article; }
friend ostream & operator << (ostream & COUT, Item & obj);
};
ostream & operator << (ostream & COUT, Item & obj){
COUT << "quantity: " << *obj._quantity << endl << obj._Article;
return COUT;
}
First class is article with constructors, destructs and overloaded operators, second class ITEM is simple it holds article and quantity.
For test in main i have following code:
Article a;
Article b("code", "name", 1.5);
Article c(b);
cout << a;
cout << b;
c++;
c++;
c.setPrice(10);
cout << c;
cout << "\n ************************************** \n";
Item _stavke[100];
for (size_t i = 0; i < 3; i++)
{
_stavke[i].getArticle().setPrice(100);
cout << _stavke[i];
cout << "\n \t\t\t ---- \n";
}
First part of code where i test Article class and some of overloaded operators it works fine but second part where i have Item _stavke[100]; array i can list members of array - no problem but any invoked change is not accepted basicly code
_stavke[i].getArticle().setPrice(100);
does not do anything it seems ...
Can anyone point me where i am going wrong and why i can not change members of array?
Thank you in advance

Your getArticle() call returns _Article by value. That is, a copy of article. Your setPrice() is invoked on the copy, so it is not reflected in the original Item's article, which remains unchanged.

Related

Returning a new queue from two queue objects?

I am trying to implement the function KidsQueue which should move families with more than 3 kids to the new counter and return it as a new queue, but the counters remain unchanged and counter 3 contains family with a number of kids above 3
#include <iostream>
#include <queue>
using namespace std;
class Family
{
private:
int id, noOfElders, noOfKids;
public:
bool operator ==(const Family &f)
{
if ((this->id!= f.id) || (this->noOfElders != f.noOfElders)||(this->noOfKids != f.noOfKids))
{
return false;
}
return true;
}
bool operator !=(const Family &f)
{
return !(*this==f); //////////////////////
}
Family(int ide=0, int eld=0, int kid=0) {
noOfElders = eld;
noOfKids = kid;
id = ide;
}
Family(const Family &a) {
noOfKids = a.noOfKids;
noOfElders = a.noOfElders;
id = a.id;
}
Family operator=(Family const &a) {
this->id = a.id;
this->noOfElders = a.noOfElders;
this->noOfKids = a.noOfKids;
return *this;
}
int getnoOfkids() const {
return noOfKids;
}
int getnoOfElders() const {
return noOfElders;
}
int getid() const {
return id;
}
void setnoOfKids(int x) {
noOfKids = x;
}
void setnoOfElders(int x) {
noOfElders = x;
}
void setid(int x) {
id = x;
}
friend ostream & operator<<(ostream & out, const Family & a)
{
out << "The id of the travelers are: " << a.id << endl;
out << "The number of elders are: " << a.noOfElders << endl;
out << "The number of kids are: " << a.noOfKids << endl;
return out;
}
friend istream &operator >> (istream &in, Family &a) {
in >> a.id;
in >> a.noOfElders;
in >> a.noOfKids;
return in;
}
};
queue<Family> KidsQueue(queue<Family> &a, queue<Family> &b) {
queue <Family> newA,newB;
queue <Family> result;
while(!a.empty())
{ if(a.front().getnoOfkids()>3) {
result.push(a.front()); a.pop();
}
else {
newA.push(a.front());
a.pop();
}
}
while(!b.empty())
{ if(b.front().getnoOfkids()>3) {
result.push(b.front()); b.pop();
}
else {
newB.push(b.front());
b.pop();
}
}
a=newA;
b=newB;
return result;
}
//print Queue
ostream &operator<<(ostream &out, const queue<Family> &q) {
queue<Family> tmp = q;
while (!tmp.empty()) {
cout << tmp.front() << endl;
tmp.pop();
}
return out;
}
int main() {
queue <Family> counter1;
queue <Family> counter2;
queue <Family> counter3;
counter1.push(Family(100, 2, 3));
counter1.push(Family(200, 2));
counter1.push(Family(400, 1));
counter1.push(Family(402, 1,4));
counter1.push(Family(789, 2));
counter2.push(Family(300, 2, 1));
counter2.push(Family(500, 1, 3));
counter2.push(Family(405, 3, 2));
counter2.push(Family(309, 1, 3));
counter2.push(Family(567, 2));
counter3 = KidsQueue(counter1, counter2);
cout << "Counter 3 has: " << endl << counter3;
cout << "Counter 1 after modification has: \n" << counter1;
cout << "Counter 2 after modification has: " << endl << counter2;
system("pause");
return 0;
}

write out array created as pointer in subclass (C++)

In the main, I'm trying to write out all items that are added to the shopping cart. I posted my whole program for context of what is happening throughout. Currently, the program outputs the memory location of the pointer, but I'm terribly confused on how to de-reference it as nothing I've tried seems to work. Now, I think I'm going about this wrong, but I'm not sure how to simply implement printing out the items in the cart. Thank you so much for any help.
#include <iostream>
#include <string>
using namespace std;
class item{
private:
string title;
string description;
float price;
public:
item(string t, string d, float p){
this -> title = t;
this -> description = d;
this -> price = p;
}
//setters
void setTitle(string title){}
void setDescription(string description){}
void setPrice(float price){}
//getters
string getTitle(){
return title;
}
string getDescription(){
return description;
}
float getPrice(){
return price;
}
//virtual print function
virtual void print(){
cout << "Description: " << description << endl;
}
};//end class item____________________________________________________
class book : public item{
private:
int pageCount;
public :
//book();
book(string t, string d, float p, int pageCount) : item(t, d, p){
}
void setPageCount(int pageCount){}
int getPageCount(){
return pageCount;
}
void print(){
cout << "Type: Book \n";
//cout << "Description: " << description << endl;
}
};//end subclass book_________________________________________________________
class movie : public item{
private:
float length;
public:
movie(string t, string d, float p, float length) : item(t, d, p){
}
void setLength(float length){}
float getLength(){
return length;
}
void print(){
cout << "Type: Movie \n";
//cout << "Description: " << d << endl;
}
};//_______________________________________________________________________
class CD : public item{
private:
int trackCount;
public:
CD(string t, string d, float p, int trackCount) : item(t, d, p){
}
void setTrackCount(int trackCount){}
int getTrackCount(){
return trackCount;
}
void print(){
cout << "Type: CD \n";
//cout << "Description: " << description << endl;
}
};//___________________________________________________________________________
class ShoppingCart{
private:
int maxItems;
item** items;
public:
ShoppingCart(int maxItems){
this-> maxItems = maxItems;
this-> items = new item*[maxItems];
for (int i = 0; i < maxItems; i++){
//fills array with nothing, will store all items here
items[i] = nullptr;
}
}
void addItem(item* item){
for (int i = 1; i <= maxItems; i++){
if (this->items[i] == nullptr) {//check for empty spot in array
this->items[i] = item; //adds the item here
break; // exits if
}
}
}
void setMaxItems(int maxItems){}
int getMaxItems(){
return maxItems;
}
int getItemCount(){
int count = 0;
for (int i = 1; i <= maxItems; i++){
if (this->items[i] != nullptr){
count++;
}
}
return count;
}
void listItems(){
for (int i = 1; i < maxItems ; i ++){
if (this->items[i] != nullptr){
cout << "Item " << i <<
": "<< (items[i]) << endl;
}
}
}
item* getItemNum(int num){
return items[num];
}
};//____________________________________________________________
int main(){
book book_dawkins("The Selfish Gene", "Genetics", 8.75, 344);
Jacob.addItem(&book_dawkins);
Jacob.listItems(); //this outputs "Item 1: 0x61fd40"
return 0;
}
Dereferencing the pointer for printing is just a matter of doing cout << *items[i] . However, this will only work once you define the proper overload for printing an item.
First, implement a virtual function for item (and an override in book) that prints this onto an ostream&:
virtual ostream& print(ostream& os) const;
Next, use this in a overload for operator <<:
ostream& operator<<(ostream& os, const item& i) {
return i.print(os);
}
Taking a reference here is crucial, as it allows looking up the correct print method at run-time.

Compilation error in C++ when using an assignment operator =?

I have written a program which was given to me as a homework assignment (it's a bit longer). The issue is that it compiles in CodeBlocks but it does not compile in Visual Studio 2017 it says - binary '=': no operator found which takes a right-hand operand of type 'CAutomobile' (or there is no acceptable conversion.
I would like to ask why is that because I could not myself find the error? I tried commenting the operator =function but still the error remained.
#include <iostream>
#include <algorithm>
#include <string>
#include <stdlib.h>
using namespace std;
class CVehicle {
string name;
int year;
public:
CVehicle() {
name = "Car";
year = 1990;
}
CVehicle(string n, int y) {
name = n;
year = y;
}
CVehicle(const CVehicle& vc) {
name = vc.name;
year = vc.year;
}
void setName(string n) {
name = n;
}
void setYear(int y) {
year = y;
}
string getName() {
return name;
}
int& getYear() {
return year;
}
virtual void Print(ostream& os) = 0;
};
class CAutomobile :public CVehicle {
double litres;
public:
CAutomobile() :CVehicle() {
litres = 7.2;
}
CAutomobile(string nm, int yr, double l) :CVehicle(nm, yr) {
litres = l;
}
void setLitres(double l) {
l = litres;
}
double& getLitres() {
return litres;
}
void Print(ostream& os) override {
os << getName() << endl;
os << getYear() << endl;
os << litres << endl;
}
friend bool operator< (CAutomobile a1, CAutomobile a2) {
if (a1.litres < a2.litres) {
return true;
}
return false;
}
CAutomobile operator= (CAutomobile& at) {
CAutomobile au;
au.getName() = at.getName();
au.getYear() = at.getYear();
au.getLitres() = at.getLitres();
return au;
}
CAutomobile operator+(CAutomobile aut) {
CAutomobile a;
a.getLitres() = getLitres() + aut.getLitres();
return a;
}
friend ostream& operator<< (ostream& o, CAutomobile a) {
o << a.getName() << endl;
o << a.getYear() << endl;
o << a.getLitres() << endl;
return o;
}
};
int main()
{
CAutomobile a[] = {
CAutomobile(),
CAutomobile("Wolkswagen",1970,80.5),
CAutomobile("Fiat",1979,21.9),
CAutomobile("Opel",1978,13.7)
};
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
cout << "Name" << ' ' << a[i].getName() << endl;
cout << "Year" << ' ' << a[i].getYear() << endl;
cout << "Litres" << ' ' << a[i].getLitres() << endl;
}
int range = 2016 - 1990 + 1;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
a[i].setLitres(rand() % 100 + 1);
a[i].setYear(rand() % range + 1996);
}
//сортираме масива по литри и извеждаме
//най малкия (първия) му елемент
for (int i = 0; i < sizeof(a-1); i++) {
for (int j = 0; j < sizeof(a-1); j++) {
if (a[j].getLitres() > a[j + 1].getLitres()) {
swap(a[j], a[j + 1]);
}
}
}
cout << a[0] << endl;
CAutomobile k = a[0] + a[3];
cout << k.getLitres() << endl;
}
CAutomobile::operator = is completely wrong. It takes a non-const reference and assignes its field to a new object. Instead it should take a const reference and modify current object.
CAutomobile & operator =(CAutomobile const & other)
{
assert(this != ::std::addressof(other)); // check for self-assignment
SetName(other.getName());
SetYear(other.getYear());
SetLitres(other.getLitres());
return *this;
}
This will bring up another problem: getters are not const-qualified, so they should be fixes as well:
string const & getName(void) const {
return name;
}
int const & getYear(void) const {
return year;
}

operators overloading, odd seg fault, classes, c++

I was given an exercise on overloading operators by my tutor. He gave me the int main() function which cannot be changed. I was supposed to write the functions etc so that the code would work. Unfortunately I have a seg fault. I've noticed that if the
TSeries series4=series1(2,4);
cout << "Series4: " << series4 << endl;
lines are commented it's more or less working. I would be very grateful for your help.
#include <iostream>
class TSeries {
public:
TSeries()
{
_size = 0;
_capacity = 0;
_tab = NULL;
}
TSeries(float *tab, const int size)
{
_tab = new float[size];
for (int i = 0; i < size; i++) _tab[i] = tab[i];
_size = size;
_capacity = 0;
}
~TSeries() { delete[] _tab; }
TSeries & operator+=(float value) { return insert(value); }
TSeries & operator,(float value) { return insert(value); }
TSeries & operator+(const TSeries & s)
{
// if(this->_size != s._size) std::cout<<"Size doesn't match!"<<std::endl;
/*else
{
std::cout<<"whee";
for(int i; i<this->_size;i++)
{
//this->_tab[i] += s._tab[i];
std::cout<<"nothing";
}
return *this;
}*/
//std::cout<<"sth";
}
TSeries & operator()(int position1, int position2)
{
// return *this;
}
TSeries & insert(float k)
{
if (_size >= _capacity) Enlarge();
_tab[_size++] = k;
return *this;
}
friend std::ostream & operator<<(std::ostream & out, const TSeries & s);
private:
int _size, _capacity;
float *_tab, *_itr;
static int _nr;
void Enlarge()
{
_capacity = 2 * _capacity + 1;
float *tmp = new float[_capacity];
for (int i = 0; i < _size; ++i)
{
tmp[i] = _tab[i];
}
delete[] _tab;
_tab = tmp;
}
};
std::ostream & operator<<(std::ostream & out, const TSeries & s)
{
int przedostatni = s._size - 1;
out << "(";
for (int i = 0; i < s._size; i++)
{
out << (int)s._tab[i];
if (i != przedostatni)
out << ",";
}
out << ")" << std::endl;
}
using namespace std;
int main(int argc, char **argv) {
TSeries series1;
series1 += 1., 2., 4., 2.;
cout << "Series1: " << series1 << endl;
const int size = 7;
float tab[size] = { 3.,3.,3.,4.,5.,1.,0. };
const TSeries series2(tab, size);
cout << "Series2: " << series2 << endl << endl;
TSeries series3 = series1 + series2;
cout << "Series3: " << series3 << endl << endl;
series1 += 1., 0., 3.;
series3 = series1 + series2;
cout << " " << series1 << endl;
cout << " +" << series2 << endl;
cout << " ---------------------" << endl;
cout << "Series3: " << series3 << endl << endl;
TSeries series4 = series1(2, 4);
cout << "Series4: " << series4 << endl;
return 0;
}
/* output required:
Series1: (1,2,4,2)
Series2: (3,3,3,4,5,1,0)
Size doesn't match!
Series3: ()
(1,2,4,2,1,0,3)
+(3,3,3,4,5,1,0)
---------------------
Series3: (4,5,7,6,6,1,3)
Series4: (4,2)
*/
std::ostream & operator<<(std::ostream & out, const TSeries & s) doesn't return anything. Please add a return out at the end of the function
operator() and operator+ should both end with return *this
As Devolus already pointed out: You don't have a copy constructor and no operator=(const TSeries&) defined
You can use memcpy to copy the arrays faster.#
The i in the for-loop in operator+(const TSeries&) isn't initialized.
Your operator(int, int) does currently alter the original object. This doesn't seem right.
Code:
#include <iostream>
class TSeries {
public:
TSeries()
{
_size = 0;
_capacity = 0;
_tab = NULL;
}
TSeries(float *tab, const int size)
{
_size = size;
_capacity = 0;
_tab = new float[size];
memcpy(_tab, tab, _size*sizeof(float));
}
TSeries(const TSeries& other)
{
_size = other._size;
_capacity = other._capacity;
_tab = new float[_size];
memcpy(_tab, other._tab, _size*sizeof(float));
}
~TSeries()
{
delete[] _tab;
}
TSeries & operator+=(float value) { return insert(value); }
TSeries & operator,(float value) { return insert(value); }
TSeries & operator+(const TSeries & other)
{
if (this->_size != other._size)
{
std::cout << "Size doesn't match!" << std::endl;
}
else
{
//std::cout << "whee";
for (int i = 0; i < this->_size; i++)
{
_tab[i] += other._tab[i];
//std::cout << "nothing";
}
}
//std::cout<<"sth";
return *this;
}
TSeries& operator=(const TSeries& other)
{
_size = other._size;
_capacity = other._capacity;
//Create tmp in case of self-assignment
float *tmp = new float[_capacity];
memcpy(tmp, other._tab, _size*sizeof(float));
delete[] _tab;
_tab = tmp;
return *this;
}
TSeries operator()(int position1, int position2)
{
//TODO: Range-Check
return TSeries(_tab + position1, position2 - position1);
}
TSeries & insert(float k)
{
if (_size >= _capacity) Enlarge();
_tab[_size++] = k;
return *this;
}
friend std::ostream & operator<<(std::ostream & out, const TSeries & s);
private:
int _size, _capacity;
float *_tab, *_itr;
static int _nr;
void Enlarge()
{
_capacity = 2 * _capacity + 1;
float *tmp = new float[_capacity];
memcpy(tmp, _tab, _size*sizeof(float));
delete[] _tab;
_tab = tmp;
}
};
std::ostream & operator<<(std::ostream & out, const TSeries & s)
{
int przedostatni = s._size - 1;
out << "(";
for (int i = 0; i < s._size; i++)
{
out << (int)s._tab[i];
if (i != przedostatni)
out << ",";
}
out << ")" << std::endl;
return out;
}
using namespace std;
int main(int argc, char **argv) {
TSeries series1;
series1 += 1., 2., 4., 2.;
cout << "Series1: " << series1 << endl;
const int size = 7;
float tab[size] = { 3.,3.,3.,4.,5.,1.,0. };
const TSeries series2(tab, size);
cout << "Series2: " << series2 << endl << endl;
TSeries series3 = series1 + series2;
cout << "Series3: " << series3 << endl << endl;
series1 += 1., 0., 3.;
series3 = series1 + series2;
cout << " " << series1 << endl;
cout << " +" << series2 << endl;
cout << " ---------------------" << endl;
cout << "Series3: " << series3 << endl << endl;
TSeries series4 = series1(2, 4);
cout << "Series4: " << series4 << endl;
return 0;
}
/* output required:
Series1: (1,2,4,2)
Series2: (3,3,3,4,5,1,0)
Size doesn't match!
Series3: ()
(1,2,4,2,1,0,3)
+(3,3,3,4,5,1,0)
---------------------
Series3: (4,5,7,6,6,1,3)
Series4: (4,2)
*/
Output
Series1: (1,2,4,2)
Series2: (3,3,3,4,5,1,0)
Size doesn't match!
Series3: (1,2,4,2)
(4,5,7,6,6,1,3)
+(3,3,3,4,5,1,0)
---------------------
Series3: (4,5,7,6,6,1,3)
Series4: (7,6)
UPDATE:
Your operator+(const TSeries &) should look somewhat like this:
TSeries operator+(const TSeries & other)
{
if (this->_size != other._size)
{
std::cout << "Size doesn't match!" << std::endl;
return TSeries(); //Return empty object
}
TSeries tmp(*this); //Create copy
for (int i = 0; i < tmp._size; i++)
{
tmp._tab[i] += other._tab[i];
}
return tmp;
}
And your operator()(int, int) like this:
TSeries operator()(int position1, int position2)
{
if (position1 < 0) position1 = 0;
else if (position1 >= _size) position1 = _size - 1;
if (position2 < position1) position2 = position1;
else if (position2 >= _size) position2 = _size - 1;
return TSeries(_tab + position1, position2 - position1);
}
Maybe you want to throw exceptions in the error cases?

Odd output from program when entering operator?

I'm probably missing something obvious here. This is my code (I'm just learning true C++, and I want to get some practice):
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char * value;
int len;
friend ostream & operator<<(ostream & os, String s);
public:
String();
String(const char * base);
~String();
String operator+(String s);
String operator*(int n);
int length();
};
String::String() {
this->value = new char[0];
this->len = 0;
}
String::String(const char * base) {
this->value = new char[this->len = strlen(base)];
strcpy(this->value, base);
}
String::~String() {
delete [] this->value;
}
int String::length() {
return this->len;
}
String String::operator+(String s) {
String n;
delete [] n.value;
cout << "Upon entering, I am: \"" << *this << "\"\n";
n.value = new char[this->len + s.len];
for(int i = 0; i < this->len; i++) {
n.value[i] = this->value[i];
}
for(int i = 0; i < s.len; i++) {
n.value[i + this->len] = s.value[i];
}
n.len = this->len + s.len;
cout << "String::operator+(" << *this << ", " << s << ") succeeded with new value = \"" << n << "\"\n";
return n;
}
String String::operator*(int n) {
String s;
delete [] s.value;
s.value = new char[this->len * n];
for(int i = 0; i < this->len * n; i++) {
s.value[i] = this->value[i % this->len];
}
cout << "String::operator* succeeded with new value = \"" << s << "\"\n";
return s;
}
ostream & operator<<(ostream & os, String s) {
return os << s.value;
}
int main() {
String s("Hello, world!");
cout << s << "\nLength = " << s.length() << "\n\n";
cout << (s + String("\n")) * 5;
return 0;
}
And the string initializes and displays correctly, but my output is really strange; it seems that upon entering the operator+, "Hello, world!" suddenly becomes "x%r"?
C:\Users\Ryan\Documents\My Dropbox\C++ Projects>strings
Hello, world!
Length = 13
Upon entering, I am: "x%r"
String::operator+(x%r,
) succeeded with new value = "x%r"
String::operator* succeeded with new value = "╚%r"
─
Try this:
ostream & operator<<(ostream & os, const String& s) {
return os << s.value;
}
otherwise your should define copy constructor for your String class.
You need to provide copy constructor and assignment operator.
There are a lot of problems with your code.
You are managing your own memory. You should avoid doing this if at all possible.
You are consitantly forgetting that strings have a null terminator. In order to accomodate the strin Hello, world! you need a char buffer that is 14 bytes, not 13.
You have a len member variable that does effectively the same thing as the strlen function, except for the inconsistent consideration of #1 above.
Your string class does not have a copy constructor, which results in wild pointers and eventually crashes.
Here is a refactoring of your code that pretty much works.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char * value;
// size_t len;
friend ostream & operator<<(ostream & os, String s);
public:
String();
String(const char * base);
String(const String& rhs)
{
value = new char[strlen(rhs.value)+1];
strcpy(value,rhs.value);
}
~String();
String operator+(String s);
String operator*(int n);
size_t length();
};
String::String() {
this->value = new char[0];
}
String::String(const char * base) {
this->value = new char[strlen(base)+1];
strcpy(this->value, base);
}
String::~String() {
delete [] this->value;
}
size_t String::length() {
return strlen(value);
}
String String::operator+(String s) {
String n;
delete [] n.value;
cout << "Upon entering, I am: \"" << *this << "\"\n";
n.value = new char[strlen(value)+strlen(s.value)+1];
for(int i = 0; i < strlen(value); i++) {
n.value[i] = this->value[i];
}
for(int i = 0; i < strlen(s.value); i++) {
n.value[i + strlen(value)] = s.value[i];
}
n.value[strlen(value)+strlen(s.value)] = '\0';
cout << "String::operator+(" << *this << ", " << s << ") succeeded with new value = \"" << n << "\"\n";
return n;
}
String String::operator*(int n) {
String s;
delete [] s.value;
s.value = new char[(strlen(value)*n)+1];
for(int i = 0; i < strlen(value) * n; i++) {
s.value[i] = this->value[i % strlen(value)];
}
s.value[strlen(value)*n] = '\0';
cout << "String::operator* succeeded with new value = \"" << s << "\"\n";
return s;
}
ostream & operator<<(ostream & os, String s) {
return os << s.value;
}
int main() {
String s("Hello, world!");
cout << s << "\nLength = " << s.length() << "\n\n";
cout << (s + String("\n")) * 5;
return 0;
}