0

I am new to C++ programming. I am using Visual Studio Code, my code:

#include <iostream>
using namespace std;

class Calculator;

class Complex
{
    float a, b;
    string Operation;
    string name;

    friend class Calculator;

public:
    Complex(float, float, string, string);
    Complex(float);
    Complex();
    Complex(Complex &, string);

    void PrintComp(string op = "None")
    {
        if (op != "None" && name != "None")
        {
            cout << "\nBy " << op << " of z1 and z2:\n"
                 << name << " = " << a << " + " << b << "i\n";
        }
        else if (name != "None")
        {
            cout << name << " = " << a << " + " << b << "i\n";
        }
        else
        {
            cout << a << " + " << b << "i\n";
        }
    }
};

Complex ::Complex(float x, float y, string givnname = "None", string operation = "None")
{
    a = x;
    b = y;
    name = givnname;
    PrintComp(operation);
}
Complex ::Complex(float x)
{
    a = x;
    b = 0;
}
Complex ::Complex()
{
    a = 0;
    b = 0;
}
Complex::Complex(Complex &obj, string givnname="None")
{
    a = obj.a;
    b = obj.b;
    name = givnname;
    cout << "Copy Cons called!"<< endl;
    PrintComp();
}

class Calculator
{
public:
    float SumRealComp(Complex const&, Complex const&);
    float SumImgComp(Complex const&, Complex const&);
};

float Calculator ::SumRealComp(Complex const &obj1, Complex const & obj2)
{
    return (obj1.a + obj2.a);
}
float Calculator ::SumImgComp(Complex const & obj1, Complex const & obj2)
{
    return (obj1.b + obj2.b);
}

int main()
{
    Complex z1(3, 5, "z1"), z2(4, 4, "z2");

    Calculator calc;

    Complex z3(calc.SumRealComp(z1, z2), calc.SumImgComp(z1, z2), "z3", "Sum");

    Complex z4(z1, "z4");

    return 0;
}

According to above code, I am using copy Constructor at the last, but Copy Constructor is called at formation of every object. Even when args of both are different. Why it is so? I am learning from here.
Every suggestions in my code are appreciated.
Thanks!

  • 1
    `Complex(Complex &, string);` is not a copy constructor; `Complex(Complex const &);` is the expected signature for a copy constructor see [Copy constructors](https://en.cppreference.com/w/cpp/language/copy_constructor) – Richard Critten Sep 12 '21 at 11:39
  • 1
    @RichardCritten, The second parameter of `Complex(Complex&, string);` has a default value, which could be a Copy Constructor. – Ghasem Ramezani Sep 12 '21 at 11:43
  • @GhasemRamezani but the 1st parameter is a non-const reference - this is also unusual as it can't bind to a temporary. As a teaching/learning practice this is bad code. – Richard Critten Sep 12 '21 at 11:45
  • 1
    @RichardCritten, `X::X` is a copy constructor if it's first parameter is of type `X&`, `X const&`, `X volatile&` or `X const volatile&`. https://eel.is/c++draft/class.copy.ctor – Ghasem Ramezani Sep 12 '21 at 11:47
  • 2
    @GhasemRamezani agreed - but any other than `X const&` should not really be in a exercise introducing the copy constructor as how the other forms should be used is much more advanced. – Richard Critten Sep 12 '21 at 11:48
  • `name = name;` doesn't do what I presume you think it does. – Eljay Sep 12 '21 at 12:09

1 Answers1

1

You will take a copy of Complex object on those functions:

Calculator::SumRealComp(Complex, Complex);
Calculator::SumImgComp(Complex, Complex);

So, on every call to those functions, you take two copies of the Complex object. You could pass a Complex const& object to avoid copy:

Calculator::SumRealComp(Complex const&, Complex const&);
Calculator::SumImgComp(Complex const&, Complex const&);

Copy Constructor

A copy constructor is one of the Class Special Member Functions, And called whenever we try to take a copy of the object:

class X;
void f(X); 

X x;
f(x); // <--- Here

X another(x); // <--- Here
X yet_another = x; // <--- And here

In the commented sections we could call the X copy constructor. A copy constructor could be defined as the following signatures:

X::X(X&);
X::X(X const&);
X::X(X volatile&);
X::X(X const volatile&);

Note: Like your code, we could add additional parameters to the copy constructor while they have a default value).
Note: For more information: Read Chapter 17 of "The C++ Programming Language" by Bjarne Stroustrup.


This is not related to your question and are my suggestions to your code, If you don't like it you could skipped(or edit it and remove it)

Some Code Review Suggestions:

  1. Stop using using namespace std; which could cause Undefined Behavior and give you a hard debugging time: Why is "using namespace std;" considered bad practice?
  2. Don't complicate the Copy Constructor signature if not necessary. You could rewrite the copy constructor as follow:
Complex::Complex(Complex const& obj)
    : a(obj.a)
    , b(obj.b)
    , name(obj.name)
{
    cout << "Copy Cons called!" << endl;
    PrintComp();
}
  1. Initialize member variables using Member Initialize List.
Ghasem Ramezani
  • 2,683
  • 1
  • 13
  • 32
  • Thanks @GhasemRamezani All your suggestions are great and helpful for me. But I am not able to understand the syntax of copy Constructor you made. Will you please clarify it? – adityanithariya Sep 12 '21 at 12:03
  • I didn't understood this: : a(obj.a) , b(obj.b) , name(obj.name) – adityanithariya Sep 12 '21 at 12:15
  • 1
    @AdityaSoni, Take a good [Book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) and read it, those are basics. – Ghasem Ramezani Sep 12 '21 at 12:17