views:

261

answers:

3

Hi,

I have an assignment for my first OOP class, and I understand all of it including the following statement:

You should create a class called ComplexNumber. This class will contain the real and imaginary parts of the complex number in private data members defined as doubles. Your class should contain a constructor that allows the data members of the imaginary number to be specified as parameters of the constructor. A default (non-parameterized) constructor should initialize the data members to 0.0.

Of course I know how to create these constructors without chaining them together, and the assignment does not require chaining them, but I want to as I just like to.

Without chaining them together, my constructors look like this:

class ComplexNumber
{
    private double realPart;
    private double complexPart;

    public ComplexNumber()
    {
         realPart = 0.0;
         complexPart = 0.0
    }

    public ComplexNumber(double r, double c)
    {
         realPart = r;
         complexPart = c;
    }
    // the rest of my class code...
}

Thanks!

+9  A: 

Is this what you're looking for?

public ComplexNumber()
    : this(0.0, 0.0)
{
}

public ComplexNumber(double r, double c)
{
     realPart = r;
     complexPart = c;
}
Rex M
Ahh, yes, initializes them both to 0.0, thanks! I am still trying to grasp the concept of constructor-chaining, so it works, but why/how?My professor has not touched constructor-chaining, nor will he, but I want to learn how to use it.
Alex
@Alex it's pretty similar to calling other methods, except constructors don't have names - so instead of `this.Method()` we just call `this()`, or to call a constructor on a parent/superclass, `base()`
Rex M
Just like method chaining; you are calling constructor B from constructor A with the arguments required by B.
Ed Swangren
OK, appreciate the help, one more question, what if I want to construct my data members to 0 in my default constructor, but my paramed constructor takes some object(s), whereas my data members are ints, doubles, floats, etc.?
Alex
@Alex: where would your non-default constructor take initial values for members, then? In any case... constructor chaining is a convenience construct. Use it when it makes sense, not all the time.
Pavel Minaev
Thanks for the answer Rex, and thanks to you Pavel for the great explanation!
Alex
+3  A: 

@Rex has the connect answer for chaining.

However in this case chaining or any initialization is not necessary. The CLR will initialize fields to their default value during object constructor. For doubles this will cause them to be initialized to 0.0. So the assignment in the default constructor case is not strictly necessary.

Some people prefer to explicitly initialize their fields for documentation or readability though.

JaredPar
thanks for the explanation, but is it ever absolutely necessary to create a default constructor? (in c#)
Alex
For certain serialization processes, yes.
Mike Chess
One place where I have found the default constructor to be required was when doing databinding against certain objects (datagridview for example)
David Hall
Your class is a typical "value class" (i.e. it represents some value, and its object identity by itself doesn't hold any semantic meaning. For such classes, it is reasonable to have a default/"zero" value, just as proper value types - `int`, `bool`, etc - do. So a default constructor makes sense for consistency reasons - just as I can write `new int()` and get `0`, I should be able to write `new ComplexNumber()`, and get `0+0i`. In general, however, not all classes need default constructors, and many specifically do _not_ need one - when object _requires_ some external data to initialize.
Pavel Minaev
A: 

I am still trying to grasp the concept of constructor-chaining, so it works, but why/how?

The 'how' of constructor chaining by using the 'this' keyword in the constructor definition, and shown in Rex M's example.

The 'why' of constructor chaining is to reuse the implementation of a constructor. If the implementation (body) of the 2nd constructor were long and complicated, then you'd want to reuse it (i.e. chain to it or invoke it) instead of copy-and-pasting it into other constructors. An alternative might be to put that code, which is shared between several constructors, into a common subroutine which is invoked from several constructors: however, this subroutine wouldn't be allowed to initialize readonly fields (which can only be initialized from a constructor and not from a subroutine), so constructor chaining is a work-around for that.

ChrisW