Hello World in D! – Part 2

As discussed in my post http://www.naresh.se/?p=5, I am trying to do a comparison between programs written in C++ and D. Why I am doing it is a question not to be asked but in any case, I am bored and would like to do something fun. I thought this is the nice way to have fun. We are going to write a Complex class and a main to test it and compare it with D. I am using Code::Blocks and mingW for C++ and Code::Blocks and Digital Mars D compiler for D. Saying that, read the previous post to know how to use Code::Blocks (CB) or RTFM.

I have created the following code for Complex.h file:

#ifndef __COMPLEX_H_INCLUDED__
#define __COMPLEX_H_INCLUDED__

class CComplex
{
private:
    double dA;
    double dB;
public:
    // default constructor
    CComplex();

    // Copy constructor
    CComplex(const CComplex &aComplex);

    // Overloaded constructor
    CComplex(double aA, double aB);

    // Access functions setters
    void setValueA(double aA);
    void setValueB(double aB);

    // Access functions getters
    double getValueA();
    double getValueB();

    // Overloaded operators
    CComplex& operator = (const CComplex &aComplex);
    CComplex& operator += (const CComplex &aComplex);
    CComplex& operator -= (const CComplex &aComplex);

    const CComplex operator + (const CComplex &aComplex) const;
    const CComplex operator - (const CComplex &aComplex) const;
    bool operator == (const CComplex &aComplex) const;
    bool operator != (const CComplex &aComplex) const;

    // More interesting overloads for * & /
    const CComplex operator * (const CComplex &aComplex) const;
    const CComplex operator / (const CComplex &aComplex) const;

    // Utility functions
    void vPrintComplexNumbers(); // prints the complex number
};

#endif // __COMPLEX_H_INCLUDED__

And the following code for Complex.cpp file:

#include "Complex.h"

#include 

using namespace std;

// default constructor
CComplex::CComplex()
{
    dA = 0; dB = 0.0;
}

// Copy constructor
CComplex::CComplex(const CComplex &aComplex)
{
    dA = aComplex.dA;
    dB = aComplex.dB;
}

// Overloaded constructor
CComplex::CComplex(double aA, double aB):dA(aA),dB(aB)
{
// Can also assign values inside the function. Lets see if compiler optimizes stuff.
// But yes, this is the mingW compiler on Win32.
}

// Access functions setters
void CComplex::setValueA(double aA)
{
    dA = aA;
}

void CComplex::setValueB(double aB)
{
    dB = aB;
}

// Access functions getters
double CComplex::getValueA()
{
    return dA;
}

double CComplex::getValueB()
{
    return dB;
}

// Overloaded operators
CComplex& CComplex::operator = (const CComplex &aComplex)
{
    // Check for self-assignment
    if(this != &aComplex)   // Not the Same Object then copy
    {
        this->dA = aComplex.dA;
        this->dB = aComplex.dB;
    }
    return *this;
}

CComplex& CComplex::operator += (const CComplex &aComplex)
{
    this->dA += aComplex.dA;
    this->dB += aComplex.dB;
    return *this;
}

CComplex& CComplex::operator -= (const CComplex &aComplex)
{
    this->dA -= aComplex.dA;
    this->dB -= aComplex.dB;
    return *this;
}

const CComplex CComplex::operator + (const CComplex &aComplex) const
{
    // Not optimized in terms of lines of code. I will leave it to the compiler to do it for me this time
    CComplex retClass = *this;
    retClass += aComplex;
    return retClass;
}

const CComplex CComplex::operator - (const CComplex &aComplex) const
{
    // Optimized call. Lets see how the compiler handles it
    return (CComplex(*this) -= aComplex);
}

const CComplex CComplex::operator * (const CComplex &aComplex) const
{
    // (a + bi).(c + di) = ac + adi + bci - bd = (ac - bd) + (ad + bc)i
    CComplex retClass(*this);

    // ac - bd
    retClass.dA *= aComplex.dA;
    retClass.dB *= aComplex.dB;
    retClass.dA = retClass.dA - retClass.dB;

    // ad + bc
    retClass.dB = (this->dA * aComplex.dB) + (this->dB * aComplex.dA);
    return retClass;
}

const CComplex CComplex::operator / (const CComplex &aComplex) const
{
/*
     (ac + bd)        (bc - ad)
    = ---------   +  i-----------
      (c2 + d2)        (c2 + d2)
*/
    CComplex retClass(*this);
    double c2d2 = (aComplex.dA * aComplex.dA) + (aComplex.dB * aComplex.dB);

    // ac + bd
    retClass.dA *= aComplex.dA;
    retClass.dB *= aComplex.dB;
    retClass.dA = retClass.dA + retClass.dB;

    // (ac+bd)/(c2+d2)
    retClass.dA = retClass.dA / c2d2;

    // bc - ad
    retClass.dB = (this->dB * aComplex.dA) - (this->dA * aComplex.dB);
    // (bc-ad)/(c2+d2)
    retClass.dB = retClass.dB / c2d2;

    return retClass;
}

bool CComplex::operator == (const CComplex &aComplex) const
{
    if(dA == aComplex.dA && dB == aComplex.dB)
    {
        return true;
    }
    return false;
}

bool CComplex::operator != (const CComplex &aComplex) const
{
    return !(*this == aComplex);
}

// Utility functions
void CComplex::vPrintComplexNumbers() // prints the complex number
{
    cout<

And forgot to put in the main.cpp file but here it is. Copy the following code into main.cpp and off you go...

#include 

#include "Complex.h"

using namespace std;

int main()
{
    CComplex a(2,3), b(a), c;
    a.vPrintComplexNumbers();
    b.vPrintComplexNumbers();
    c = a+b;
    c.vPrintComplexNumbers();
    if(a!=b)
    {
        cout << "Var a "; a.vPrintComplexNumbers();
        cout << " is not equal to Var b "; b.vPrintComplexNumbers();
    }
    else
    {
        cout << "Var a is equal to Var b with values "; a.vPrintComplexNumbers();
    }

    c += a;
    cout<<"Var c is "; c.vPrintComplexNumbers();
    c -= b;
    cout<<"Var c is "; c.vPrintComplexNumbers();

    if(c == (a+b))
        cout<<"Program works fine..."<

Okay. With this done, you can compile and run the program. Runs pretty good eh.. And time for some statistics now.

- Clean rebuild takes around 2 seconds for debug and 1 second for release on the mingw compiler with 0 errors and 0 warnings. The command line was: mingw32-g++.exe -Wall -fexceptions  -g  -pg for compiling and mingw32-g++.exe -pg -lgmon for linking

- Output executable size is 595.99 KB for debug release and 271.50 KB for release executable

- Code Statistics is: 3 files, 66% code only, 2% code + comments, 14% comments and 18% empty

- Code only lines: 155, Empty lines: 43, Comment Lines: 32, Code & Comments: 4 with a total of 234 lines

Besides this I also have a gprof output for code profiling. This post would be way too long if I paste it here especially since the blog doesn’t support any plugins. But lets move over to D now and see whats it store for us for a similar program doing similar things except that it is in D. Note that I am writing the code from scratch instead of using the D utility which converts the C/CPP headers to D files.

—- End Part 2 of Hello World in D!…