adityanithariya
adityanithariya

Reputation: 137

Copy Constructor called unexpectedly

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!

Upvotes: 0

Views: 101

Answers (1)

Ghasem Ramezani
Ghasem Ramezani

Reputation: 2888

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.

Upvotes: 1

Related Questions