1
\$\begingroup\$

I know this may be a silly question, but... is it really necessary to add the parameter name (int <parameter_name>), instead of just (int) in a definition of an operator function to overload "++" ( post-increment) ? or would it be optional?

example:

/* function prototype */
friend Cylinder operator++(Cylinder&, int);

/* function definition */
Cylinder operator++(Cylinder& n, int u)
{
    Cylinder temp = n;

    (n.radius)++;
    (n.height)++;

    return (temp);
}

and here it is the same except that it does not have the name of the parameter in the definition function (I only ask, because I am curious, that even though it does not have it, the program still works, and also if it would be good practice to put it or not?):

Example:

/* function prototype */
friend Cylinder operator++(Cylinder&, int);

/* function definition */
Cylinder operator++(Cylinder& n, int)
{
    Cylinder temp = n;

    (n.radius)++;
    (n.height)++;

    return (temp);
}

Full program: main.cpp

#include <iostream>
#include <cstdlib>

#include "Cylinder.h"

using namespace std;


int
main(void)
{
    Cylinder Cylinder1(5.0, 10.0); //radius = 5.0 and height = 10.0
    Cylinder Cylinder2(3.5, 20.0); //radius = 3.5 and height 20.0
    Cylinder Cylinder3;
    Cylinder Cylinder4;
    Cylinder Cylinder5;
    
    cout << "Cylinder1 --- " << Cylinder1 << endl;
    cout << "Cylinder2 --- " << Cylinder2 << endl;


    Cylinder3 = Cylinder1 + Cylinder2;
    cout << "Cylinder1 + Cylinder2 = " << "Cylinder3 --- " << Cylinder3 << endl;

    Cylinder4 = Cylinder1 - Cylinder2;
    cout << "Cylinder1 - Cylinder2 = " << "Cylinder4 --- " << Cylinder4 << endl;

    Cylinder5 = Cylinder1 * Cylinder2;
    cout << "Cylinder1 * Cylinder2 = " << "Cylinder5 --- " << Cylinder5 << endl;

    cout << "Compare Cylinder1 > Cylinder2 --- " << endl;
    if (Cylinder1 > Cylinder2)
        cout << "Cylinder1 is greater than Cylinder2." << endl;
    else
        cout << "Cylinder1 is less than or equal to Cylinder2." << endl << endl;
    
    Cylinder1++;
    cout << "Cylinder1++ --- " << endl;
    cout << "New dimension of Cylinder1: " << Cylinder1 << endl;

    Cylinder4 = Cylinder3++;
    cout << "Cylinder4 = Cylinder3++ --- " << endl;
    cout << "New dimension of Cylinder3: " << Cylinder3 << endl;
    cout << "New dimension of Cylinder4: " << Cylinder4 << endl;

    cout << "Cylinder4 != Cylinder3 --- Cylinder4 is " 
         << (Cylinder4 != Cylinder3 ? "not equal to Cylinder3 " : "equal to Cylinder3") << endl;
    cout << "Cylinder4 >= Cylinder3 --- Cylinder4 is " 
         << (Cylinder4 >= Cylinder3 ? "greater or equal to Cylinder3 " : "less than Cylinder3 ") << endl;
    cout << "Cylinder4 == Cylinder3 --- Cylinder4 is " 
         << (Cylinder4 == Cylinder3 ? "equal to Cylinder3 " : "not equal to Cylinder3") << endl;
    cout << "Cylinder4 < Cylinder3 --- Cylinder4 is " 
         << (Cylinder4 < Cylinder3 ? "less than Cylinder3 " : "greater than or equal to Cylinder3") << endl;
    cout << "Cylinder4 <= Cylinder3 --- Cylinder4 is " 
         << (Cylinder4 <= Cylinder3 ? "less than or equal to Cylinder3 " : "greater than Cylinder3") << endl;
    exit(EXIT_SUCCESS);
}

Cylinder.cpp

#include <iostream>

#include "Cylinder.h"


Cylinder::Cylinder(void)
{
    this->radius = 1;
    this->height = 1;
}


Cylinder::Cylinder(double _radius, double _height)
{
    this->radius = _radius;
    this->height = _height;
}


const Cylinder&
Cylinder::operator=(const Cylinder &n)
{   
    this->radius = n.radius;
    this->height = n.height;

    return (*this);
}

Cylinder
Cylinder::operator+(const Cylinder& n) const
{
    Cylinder new_n;

    new_n.radius = radius + n.radius;
    new_n.height = height + n.height;
    
    return (new_n);
}


Cylinder
Cylinder::operator-(const Cylinder& n) const
{
    Cylinder new_n;

    new_n.radius = radius - n.radius;
    new_n.height = height - n.height;

    return (new_n);
}


Cylinder
Cylinder::operator*(const Cylinder& n) const
{
    Cylinder new_n;

    new_n.radius = radius * n.radius;
    new_n.height = height * n.height;

    return (new_n);
}


bool
Cylinder::operator==(const Cylinder& n) const
{
    Cylinder new_n;

    return ((new_n.radius == n.radius && 
         new_n.height == n.height)  ? true : false);
}


bool
Cylinder::operator!=(const Cylinder& n) const
{
    Cylinder new_n;

    return ((new_n.radius != n.radius && 
         new_n.height != n.height)  ? true : false);
}


bool
Cylinder::operator>=(const Cylinder& n) const
{
    Cylinder new_n;

    return ((new_n.radius >= n.radius && 
         new_n.height >= n.height)  ? true : false);
}


bool
Cylinder::operator>(const Cylinder& n) const
{
    Cylinder new_n;

    return ((new_n.radius > n.radius &&
         new_n.height > n.height)  ? true : false);
}


bool
Cylinder::operator<(const Cylinder& n) const
{
    Cylinder new_n;

    return ((new_n.radius < n.radius &&
         new_n.height < n.height)  ? true : false);
}


bool
Cylinder::operator<=(const Cylinder& n) const
{
    Cylinder new_n;

    return ((new_n.radius <= n.radius &&
         new_n.height <= n.height)  ? true : false);
}


Cylinder
operator++(Cylinder& n, int)
{
    Cylinder temp = n;

    (n.radius)++;
    (n.height)++;

    return (temp);
}

ostream &operator<<(ostream& out, const Cylinder& n)
{
    out << "Radius: " << n.radius << '\t'
        << "Height: " << n.height << std::endl; 
    return (out);
}

Cylinder.h

#ifndef CYLINDER_H_INCLUDED
#define CYLINDER_H_INCLUDED

using namespace std;


class Cylinder {

    public:
        /* function members */
        Cylinder(void);
        Cylinder(double, double);
        
        const Cylinder& operator=(const Cylinder &);

        Cylinder operator+(const Cylinder&) const;
        Cylinder operator-(const Cylinder&) const;
        Cylinder operator*(const Cylinder&) const;

        bool operator==(const Cylinder&) const;
        bool operator!=(const Cylinder&) const;
        bool operator>=(const Cylinder&) const;
        bool operator>(const Cylinder&) const;
        bool operator<(const Cylinder&) const;
        bool operator<=(const Cylinder&) const;

        friend Cylinder operator++(Cylinder&, int);
        friend ostream &operator<<(ostream& out, const Cylinder&);
        
    private:
        /* data members */
        double radius;
        double height;
};

#endif  /* CYLINDER_H_INCLUDED */
\$\endgroup\$
7
  • 1
    \$\begingroup\$ You add a cilinder to a cilinder of the same size and you get both double the height and the radius? What kind of cilinder is that? Your code is in violation of the principle of least surprise there... I'd also expect a cilinder to grow at the same speed relative to the current size, not just by a specific unit in both directions. \$\endgroup\$ Commented Feb 14, 2022 at 22:41
  • \$\begingroup\$ Well, I just tried to write the code as they told me in the instructions, I also think that there are things that don't make sense. But, since I have to follow the instructions provided by the instructor, I have no choice. \$\endgroup\$ Commented Feb 14, 2022 at 23:02
  • \$\begingroup\$ I thought that if he wanted us to practice certain things, he could have provided something else... \$\endgroup\$ Commented Feb 14, 2022 at 23:04
  • \$\begingroup\$ Well, to test the class / method / op overloading design the model doesn't have to make sense I suppose, but I would also argue that it would be easy to create a good model or a different example. Creating a design that would be shot down by anybody with good sense, well, I don't know. Maybe you could make yourself popular by recommending a better model. \$\endgroup\$ Commented Feb 14, 2022 at 23:08
  • \$\begingroup\$ You're right, since I still have time I'll try to see if I can do something much better. By the way, do you have any books you can recommend, as you can see I'm new to programming. I'd be really grateful. \$\endgroup\$ Commented Feb 14, 2022 at 23:21

1 Answer 1

4
\$\begingroup\$

Answer to your question

is it really necessary to add the parameter name (int <parameter_name>), instead of just (int) in a definition of an operator function to overload "++" ( post-increment) ? or would it be optional?

That is not necessary. If a function parameter is not used in the body of a function, you do not need to give that parameter a name.

Cylinder arithmetic doesn't make sense

What does it mean to add two cylinders together? Or to multiply them? You are implementing overloads for the arithmetic and relational operators, and just blindly apply those operators to the radius and height, but that doesn't make any sense.

Consider your cylinders are all made out of the same homogeneous material. If you add two identical cylinders together, what do you expect the result to be? Another cylinder that has double the volume? But if you add the radii and height individually, then the volume will actually increase eightfold. The same goes for mass. What if you add a cylinder with a very small radius but large height to one with a large radius but small height? If you subtract cylinders, what does it mean if the result has a negative value for both radius and height?

Your relational operators also don't make sense, at least they don't form a total order. Consider comparing two cylinders A with radius 1 and height 2, and cylinder B with radius 2 and height 1. Then operator<, operator> and operator== will all return false. Also consider that you can have two cylinders with equal radius but different height. Then both operator== and operator!= return false.

Actually, the operators don't even do that. Why are most of them creating a new Cylinder object and using that instead of this?

Use '\n' instead of std::endl

Prefer using '\n' instead of std::endl; the latter is equivalent to the former but also forces the output to be flushed, which is usually not necessary and can have a negative impact on performance.

Unnecessary code

Your code has some unnecessary parentheses and ternary operators. Consider:

return ((new_n.radius < n.radius &&
         new_n.height < n.height)  ? true : false);

First, the outer parentheses are not necessary at all. Second, the ternary operator doesn't do anything. Everything before the ? is already a boolean value, so you can just write:

return new_n.radius < n.radius && new_n.height < n.height;

operator= should return a non-const reference

operator= only makes sense on a non-const object, and the return value should also be a non-const reference.

Use () for functions that take no parameters

(void) is only necessary in C, in C++ you can just write:

Cylinder();

Prefer initializer lists to initialize member variables

While your constructors are valid, prefer using initializer lists to initialize member variables, like so:

Cylinder::Cylinder(): radius(1), height(1) {}
Cylinder::Cylinder(double radius_, double height_): radius(radius_), height(height_) {}

Or combine them using default parameter values:

Cylinder::Cylinder(double radius_ = 1, double height_ = 1): radius(radius_), height(height_) {}
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.