-2

How do I create a copy constructor that copies an object to the newly instantiated object?

Also, how do I use the == operator to compare the speed of two Tricycle objects?

Here is the sample code:

#include <iostream>

class Tricycle
{
private:
    int* speed;
  //static int speedlim;

public:
    Tricycle();
    // copy constructor and destructor use default
    int getSpeed() const { return *speed; }
  //static int getspeedlim() {return speedlim;}
    void setSpeed(int newSpeed) { *speed = newSpeed; }
    Tricycle operator=(const Tricycle&);
  void operator++();
  void operator++(int);
};

  //Tricycle operator++();
  //Tricycle operator++(Tricycle,int);

Tricycle::Tricycle()
{
    speed = new int;
    *speed = 5;
  //speedlim=40;
  }

Tricycle Tricycle::operator=(const Tricycle& rhs){ 
  
    if (this == &rhs)
        return *this;
    delete speed;
    //speed = new int;
    //*speed = rhs.getSpeed();
    return *this;
}

void Tricycle::operator++(){
  (*speed)++;}
void Tricycle::operator++(int){
  (*speed)++;}  

int main()
{
    Tricycle wichita;
  //std::cout << "the speed limit is : " << Tricycle::getspeedlim();; 
    std::cout << "Wichita's speed : " << wichita.getSpeed() << "\n";
    std::cout << "Setting Wichita's speed to 6 ...\n";
    wichita.setSpeed(6);
    Tricycle dallas;
    std::cout << "Dallas' speed : " << dallas.getSpeed() << "\n";
    std::cout << "Copying Wichita to Dallas ...\n";
    wichita = dallas;
    std::cout << "Dallas' speed : " << dallas.getSpeed() << "\n";

  wichita.setSpeed(5);
  wichita++;
  std::cout << "Wichita's speed : " << wichita.getSpeed() << "\n";

  wichita.setSpeed(5);
  ++wichita;
  std::cout << "Wichita's speed : " << wichita.getSpeed() << "\n";
  
    return 0;
}

Here is a test I tried using pre-increment and post-increment to increment the speed. This is the answer:

Wichita's speed : 5
Setting Wichita's speed to 6 ...
Dallas' speed : 5
Copying Wichita to Dallas ...
Dallas' speed : 5
Wichita's speed : 6
Wichita's speed : 6
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Light
  • 25
  • 6
  • Unrelated, but your assignment operator should return a reference: `Tricycle &`. – jkb Jul 28 '22 at 20:09
  • 1
    What's the point of using dynamically allocated memory for `speed`? If you use `int` instead you don't need to define the copy and move constructors/assignment operators, since the default ones are sufficient. The return type of the assignment operators should be a reference to the containing class though... – fabian Jul 28 '22 at 20:10
  • 2
    I recommend that you go through [this canonical implementation](https://en.cppreference.com/w/cpp/language/operators#Canonical_implementations) reference for overloading operators. All your overloaded operators are wrong. – Some programmer dude Jul 28 '22 at 20:11
  • As for the copying part, you already seem to know how to do that (well, *almost*) with your copy-assignment operator. Now think a little on how to do this in your copy-constructor. – Some programmer dude Jul 28 '22 at 20:12
  • 2
    Here's how to "create a copy constructor that copies an object to the newly instantiated object", which is what you asked: declare the constructor, it's a constructor that takes a const reference to another instance of this object. In that constructor you then proceed and initialize all members of the new object to be the same as the other object. There's nothing magical about a copy constructor, it's a constructor that's no different than any other constructor, except that its only parameter is a const reference to another instance of the same class. That's all. – Sam Varshavchik Jul 28 '22 at 20:19
  • @Some programmer dude Thanks – Light Jul 28 '22 at 20:20

1 Answers1

1

How do I create a copy constructor that copies an object to the newly instantiated object?

Like this:

class Tricycle
{
...
public:
    ...
    Tricycle(const Tricycle&);
    ...
};
    
Tricycle::Tricycle(const Tricycle &src)
{
    speed = new int;
    *speed = src.getSpeed(); // or: *(src.speed)

    // or:
    // speed = new int(src.getSpeed()); // or: *(src.speed)
}

Also, how do I use the == operator to compare the speed of two Tricycle objects?

Like this:

class Tricycle
{
...
public:
    ...
    bool operator==(const Tricycle&) const;
    ...
};
    
bool Tricycle::operator==(const Tricycle &rhs) const
{
    return getSpeed() == rhs.getSpeed();
    // or:
    // return *speed == *(rhs.speed);
}

That said, there are some other problems with your code:

  • Tricycle is missing a destructor to free the allocated speed, thus leaking it. The default compiler-generated destructor is not sufficient, just like the copy constructor and assignment operator.

  • the assignment operator= and pre-increment operator++ need to return a Tricycle& reference to *this, and the post-increment operator++ needs to return a Tricycle copy of *this before speed was updated. See What are the basic rules and idioms for operator overloading?

  • the assignment operator= is leaving speed in an invalid state. It is freeing speed but not reallocating it or setting it to NULL. There is no reason for it to free speed at all, just set its value.

Try this:

class Tricycle
{
private:
    int* speed;
    //static int speedlim;

public:
    Tricycle();
    Tricycle(const Tricycle&);
    ~Tricycle();

    int getSpeed() const { return *speed; }
    //static int getspeedlim() { return speedlim; }
    void setSpeed(int newSpeed) { *speed = newSpeed; }

    Tricycle& operator=(const Tricycle&);
    Tricycle& operator++();
    Tricycle operator++(int);
};


//int Tricycle::speedlim = 40;

Tricycle::Tricycle()
{
    speed = new int(5);
}

Tricycle::Tricycle(const Tricycle &src)
{
    speed = new int(*(src.speed));
}

Tricycle::~Tricycle()
{
    delete speed;
}

Tricycle& Tricycle::operator=(const Tricycle& rhs)
{
    if (this != &rhs)
        *speed = rhs.getSpeed();
    return *this;
}

Tricycle& Tricycle::operator++()
{
    ++(*speed);
    return *this;
}

Tricycle Tricycle::operator++(int)
{
    Tricycle temp(*this);
    ++(*speed);
    return temp;
}  

That said, there is no good reason for speed to be dynamically allocated at all. If you get rid of that allocation, then the default compiler-generated destructor, copy constructor, and copy assignment operator will be sufficient, so you don't need to define them at all:

class Tricycle
{
private:
    int speed;
    //static int speedlim;

public:
    Tricycle();

    int getSpeed() const { return speed; }
    //static int getspeedlim() { return speedlim; }
    void setSpeed(int newSpeed) { speed = newSpeed; }

    Tricycle& operator++();
    Tricycle operator++(int);
};


//int Tricycle::speedlim = 40;

Tricycle::Tricycle()
{
    speed = 5;
}

Tricycle& Tricycle::operator++()
{
    ++speed;
    return *this;
}

Tricycle Tricycle::operator++(int)
{
    Tricycle temp(*this);
    ++speed;
    return temp;
}  
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770