Advertisement

constructor implementation

Started by June 19, 2002 11:53 PM
4 comments, last by viper35al 22 years, 3 months ago
I'm reading a C++ book and I have the following code, and the book didn't appear to tell me what something means, I marked the problem part with a comment. Thanks in advance.
    

//Listing 10.2 Default values in member functions

#include <iostream.h>

// Rectangle class declaration

class Rectangle
{
public:
	// constructors

	Rectangle(int width, int height);
	~Rectangle(){}
	void DrawShape(int aWidth, int aHeight, bool UseCurrentVals =
												false) const;

private:
	int itsWidth;
	int itsHeight;
};

//Constructor implementation

Rectangle::Rectangle(int width, int height):
itsWidth(width),       
itsHeight(height)
// what does this do?  My stupid book doesn't explain it, unless

// I accidentally missed the

// explanation.



{}                     


// default values used for third parameter

void Rectangle::DrawShape(
int width,
int height,
bool UseCurrentValue
) const
{
	int printWidth;
	int printHeight;

	if (UseCurrentValue == true)
	{
		printWidth = itsWidth;       // use current class values

		printHeight = itsHeight;
	}
	else
	{
		printWidth = width;         // use parameter values

		printHeight = height;
	}


	for (int i = 0; i<printHeight; i++)
	{
		for (int j = 0; j< printWidth; j++)
		{
			cout << "*";
		}
		cout << "\n";
	}
}

// Driver program to demonstrate overloaded functions

int main()
{
	// initialize a rectangle to 30,5

	Rectangle theRect(30,5);
	cout << "DrawShape(0,0,true)...\n";
	theRect.DrawShape(0,0,true);
	cout <<"DrawShape(40,2)...\n";
	theRect.DrawShape(40,2);
	return 0;
}

    
[edited by - viper35al on June 19, 2002 12:54:25 AM]
That is called member initializer list. Instead of writing

Rectangle::Rectangle(int width, int height)
{
itsWidth = width;
itsHeight = height;
}

you initialize them using the syntax shown in the example.

The advantage is that if you''re using member initializer lists with complex objects that have their own constructors, only copy constructors will be called. If you write code the way I wrote it above, first the default constructors will be called for all objects stored in Rectangle and then assignment operators will be invoked to actually store useful values in them. It''s not an issue for built-in types, but it is for user-defined types (classes/structs).
---visit #directxdev on afternet <- not just for directx, despite the name
Advertisement
Ok,
so typing
itsWidth(width),
itsHeight(height)

is really just saying that thisvariable(=thisvariable)

I am not really clear what IndirectX said, if anyone could clarify the advantages of doing this, I would apprectiate it.

Thanks.



[edited by - viper35al on June 20, 2002 1:36:47 AM]
quote: Original post by viper35al
Ok,
so typing
itsWidth(width),
itsHeight(height)

is really just saying that thisvar(=thisvar)

I am not really clear what IndirectX said, if anyone could clarify the advantages of doing this, I would apprectiate it.

Thanks.



The main use for doing this is when you initializing a member of your class that also needs a constructor to be called. For example, suppose you have these two classes:

      class FirstClass{public:   FirstClass(int i);   ~FirstClass();private:   FirstClass();};class SecondClass{public:   SecondClass();   ~SecondClass();private:   FirstClass m_variable;};  In this case, you'll see that the only public constructor that has been defined for FirstClass requires you to pass in an integer.  By the body of SecondClass's constructor (between the {} ) all the member variables must be completely constructed.  So you would write the constructor for SecondClass something like this:      SecondClass::SecondClass():m_variable(123){}      


Hopefully, that explanation helps you out. Using the initialization list also prevent you from doing a default construction of an object and then reinitializing it with some other value in the body of the constructor.

Usually, it doesn't make much difference for built-in types such as integers whether you put them in the initialization list or in the body of the constructor.

If you're still confused, review constructors in your C++ book (or just ask another question).

Edit: a couple of small mistakes.

[edited by - jaxson on June 20, 2002 1:39:10 AM]
Ok. Suppose you have class foo.

  class foo {  int a, b;  foo(int aa, int bb);};  

There are two ways to write the constructor that will accomplish the same thing: set a to aa and b to bb.

  foo::foo(int aa, int bb)  : a(aa), b(bb){}// andfoo::foo(int aa, int bb){  a = aa;  b == bb;}  

In this example, int is a built-in type. For the two above functions, the compiler should generate exactly the same code. So neither one has any advantage over the other. Use whichever one you like more.

However, if foo has a member x of class bar, the picture is slightly different.

  class bar {  // default constructor  bar() { ... }  // copy constructor  bar(const bar& other_bar) { ... }  // assignment operator  bar& operator =(const bar& other_bar) { ... }  // more stuff};class foo {  // now we have a user-defined type as a member  bar x;  foo(const bar& xx);};  

foo''s constructor must set member variable x to xx. Again, it can be written in two ways:

  foo::foo(const bar& xx)// this line initializes x. bar''s copy constructor is called  : x(xx){}// orfoo::foo(const bar& xx){  // at this point, x must be constructed. bar''s default constructor has already been called  // the following line invokes bar''s assignment operator  x = xx;}  

Note that the member initializer list needs only copy constructor of bar to be called, while the other way needs two calls: first to the default constructor and second to the assignment operator. This is because ''x'' must be initialized when you enter constructor, and since you''re not initializing it explicitly the compiler initializes it implicitly. Thus, member initializer lists are faster for user-defined types than assignments in constructor.

If you haven''t read about copy constructors and assignment operators, do that and return to the second part of my post later.
---visit #directxdev on afternet <- not just for directx, despite the name
Oh, wait, when I read further, past that code in the book, I found that the author does explain it. (I guess from now on I''ll read a couple pages ahead before asking a question.)

Sorry for taking your time, and thanks for your responses.

This topic is closed to new replies.

Advertisement