2

I'm working on a program that is basically suppose to list IceCreams with their Ingredients, name, price and discount, to the point in the code given I'm trying to take 2 different Ice Cream names and if say the user entered Caramel Apple Delight and chocolate I need it to give me "Caramel Apple Delight + chocolate", and since I'm new to how operators works and this needs to be done with an operator I've been stuck for hours on this, I've run into a similar problem and I don't know how I can do this, I've considered to concat the strings but it doesn't make any sense when it comes to the printing part.

IceCream &operator +(const IceCream &i){
        IceCream temp;
        temp.name = strncpy(this->name) + strncat(i.name);
        if(*this>temp){
            delete [] temp.name;
            temp.name=new char [strlen(this->name)+1];
            strncpy(temp.name,this->name,strlen(this->name)+1);

        }
        return temp;
    }

This is the rest of the code and I am aware I have some issues with it but this is what I need help to solve since I'm having trouble understanding how all the operators work.

class IceCream{
    private:
    char *name;
    char ingr[100];
    float price;
    int discount;

    public:
    IceCream(){name=new char [0];}
    IceCream(char *name=" ", char* ingr=" ", float price=0.0, int discount=0){
        this->name=new char[strlen(name)+1];
        strcpy(this->name, name);
        strcpy(this->ingr,ingr);
        this->price=price;
        this->discount=discount;
    }

    IceCream(const IceCream &i){
        this->name=new char[strlen(i.name)+1];
        strcpy(this->name,i.name);
        strcpy(this->ingr,i.ingr);
        this->price=i.price;
        this->discount=i.discount;
    }

    ~IceCream(){delete [] this->name;}

    friend ostream& operator<<(ostream& out, IceCream &i){
        if(i.discount>0){
            out<<i.name<<": "<<i.ingr<<" "<<i.ingr" "<<"("i.discount")"<<endl;
        }
        else{
            out<<i.name<<": "<<i.ingr<<" "<<i.price" "<<endl;
        }
        return out;
    }


    IceCream &operator ++(int){
        discount+=5;
        return *this;
    }

    IceCream &operator +(const IceCream &i){
        IceCream temp;
        temp.name = strncpy(this->name) + strncat(i.name);
        if(*this>temp){
            delete [] temp.name;
            temp.ime=new char [strlen(this->name)+1];
            strncpy(temp.name,this->name,strlen(this->name)+1);

        }
        return temp;
    }
  • Why are you using character arrays instead of `std::string`? – Barmar Mar 27 '17 at 22:17
  • @Barmar we are required to by the guys that actually make these problems, we get minus points for using strings – Damjan Stojanovski Mar 27 '17 at 22:19
  • 1
    And if the answer to Barmar's question is "this is a homework assignment", then create a string class yourself, test it, and use it in your IceCream program instead of doing one-off dynamic memory allocation with `new[]` and `delete[]` strewn around. That way you have a string class always handy whenever you get these ridiculous requirements. – PaulMcKenzie Mar 27 '17 at 22:20
  • @PaulMcKenzie it's project exercises we need to do before our exams and we need to submit them within the boundaries given, using std::string it has no problems but I need to use dynamic memory in this which is why I'm asking for help here, for the next exam they will be asking us to use strings instead of char arrays – Damjan Stojanovski Mar 27 '17 at 22:22
  • @DamjanStojanovski I guess you didn't read my comment carefully. Nothing stops you from encapsulating all of that logic into your own string class. You already are learning operator overloading, copy constructor, assignment op, etc., so what's stopping you from creating a "MyString" class and using that? Put the tools you are being taught to good use. – PaulMcKenzie Mar 27 '17 at 22:23
  • @PaulMcKenzie oh now I just understood what you meant, I'm gonna try honestly but I can't give up on this due to the sheer anger it caused, many thanks :D – Damjan Stojanovski Mar 27 '17 at 22:24
  • You can't use `+` with arrays. You'll need to allocate space for the target array and use `strcpy()` and `strcat()` on that target array. – Barmar Mar 27 '17 at 22:25
  • @Barmar , that is what I'm trying to do but I've never used strcpy and strcat like this before which is why I'm asking here and asking how I would implement that in my code, it's a stupid question yes but I really am a slow learner – Damjan Stojanovski Mar 27 '17 at 22:27
  • @DamjanStojanovski - Note that the mistakes you're making now would have been made if you were creating your own string class. You need to allocate enough memory to hold the original string and the string you want to add at the end (plus the terminating NULL character). – PaulMcKenzie Mar 27 '17 at 22:29
  • @PaulMcKenzie I've actually not learned that since the material they send us really limited as is the time between lessons and the exams so I'm trying to figure that out now, I've ordered the book C++ Primer as it was recommended to me by everyone I asked to literature on Object Oriented programming and C++ – Damjan Stojanovski Mar 27 '17 at 22:31
  • @DamjanStojanovski -- Your `IceCream` class is missing an assignment operator. You can [start here](http://coliru.stacked-crooked.com/a/a6af19680d7c9b6d). This uses most of the code you've already written. The things missing at the link such as `operator +` for `MyString` is basically what you need to implement. But once you have that, the code inside of `IceCream` becomes very simple since all of the logic is moved to MyString. – PaulMcKenzie Mar 27 '17 at 22:51
  • @PaulMcKenzie this seems really interesting, is there anything I should else know about how the MyString class you've created works or just start off from here, thank you very much good sir :D – Damjan Stojanovski Mar 27 '17 at 23:03
  • @DamjanStojanovski Implement an assignment operator using `copy / swap` as in [this post](http://stackoverflow.com/questions/42451647/how-to-implement-an-assignment-operator-in-linked-list-class/42451683#42451683). Then you really should implement `+=`, and then `+` using `+=` (again, search SO for links on how to create `+=` and then create `+`). Once you have all of that, the `IceCream` assignment is practically done. – PaulMcKenzie Mar 28 '17 at 00:16

2 Answers2

0

You can change your design and make a better solution for this problem:

// DecoratorPattern.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>

class IiceCream
{
public:
    virtual void Make() = 0;
    virtual ~IiceCream() { }

};

class SimpleIceCream: public IiceCream
{
public:
    virtual void Make() 
    {
        std::cout<<"\n milk + sugar +  Ice cream Powder";
    }


};

class IceCreamDecorator: public IiceCream
{

public:
    IceCreamDecorator(IiceCream& decorator):m_Decorator(decorator)
    {

    }

    virtual void Make() 
    {
        m_Decorator.Make();
    }
    private:
    IiceCream& m_Decorator;
};

class WithFruits : public IceCreamDecorator
{

public:
     WithFruits(IiceCream& decorator):IceCreamDecorator(decorator)
     {

     }
     virtual void Make() 
     {
         IceCreamDecorator::Make();
         std::cout<<" + Fruits";
     }

};

class WithNuts : public IceCreamDecorator
{

public:
    WithNuts(IiceCream& decorator):IceCreamDecorator(decorator)
    {

    }

    virtual void Make() 
    {
        IceCreamDecorator::Make();
        std::cout<<" + Nuts";
    }

};

class WithWafers : public IceCreamDecorator
{

public:
    WithWafers(IiceCream& decorator):IceCreamDecorator(decorator)
    {

    }

    virtual void Make() 
    {
        IceCreamDecorator::Make();
        std::cout<<" + Wafers";
    }

};

int _tmain(int argc, _TCHAR* argv[])
{
    IiceCream* pIceCreamSimple = new SimpleIceCream();
    pIceCreamSimple->Make();

    IiceCream* pIceCreamFruits = new WithFruits(*pIceCreamSimple);
    pIceCreamFruits->Make();

    IiceCream* pIceCreamNuts   = new WithNuts(*pIceCreamFruits);
    pIceCreamNuts->Make();

    IiceCream* pIceCreamWafers = new WithWafers(*pIceCreamNuts);
    pIceCreamWafers->Make();

    delete pIceCreamSimple;
    delete pIceCreamFruits;
    delete pIceCreamNuts;
    delete pIceCreamWafers;

    return 0;
}

This solution use decorator design pattern.

Sam Mokari
  • 461
  • 3
  • 11
0

You can't use + to concatenate char arrays. You need to allocate space for the new string with new, then copy and concatenate into that.

IceCream &operator +(const IceCream &i){
    IceCream temp;
    delete[] temp.name; // Free the string allocated by the default constructor
    temp.name = new char[strlen(this->name) + strlen(i.name) + 1];
    strcpy(temp.name, this->name);
    strcat(temp.name, i.name);
    return temp;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612