Click to See Complete Forum and Search --> : Two points make the job done?! Why?


cougar autumn
December 24th, 2001, 03:44 AM
One of my fellow programer came into such a problem: how to initialize a class with two private variables contained in another class' constructor.
Why initialization in this way can get the job down?
Thanks in advance.

#include <iostream.h>
class B
{
public:
B(){};
B(int i, int j);
void printb();
private:
int a , b;
};

B::B(int i,int j)
{
a=i;
b=j;
}

void B::printb()
{
cout<<"a="<<a<<",b="<<b<<endl;
}





class A
{
publcic:
A(){};
A(int i, int j);
void printa();
private:
B c;
};



A::A(int i,int j):c(i,j) // the special usage of initialization, private value of i and j can be initializated
{
}

void A::printa()
{
c.printb();
}


void main()
{
A m(7,9);
m.printa();
}


VC++ developer

Igor Soukhov
December 24th, 2001, 04:24 AM
Hi !

The code you posted compiles and works OK. (only thing I corrected is publicic type just before class A constructors)

Please - rate answer if it helped you
It gives me inspiration when I see myself in the top list =)

Best regards,

-----------
Igor Soukhov (Brainbench/Tekmetrics ID:50759)
igor@soukhov.com | ICQ:57404554 | http://soukhov.com

Russian Software Developer Network http://rsdn.ru

NMTop40
December 24th, 2001, 04:34 AM
I don't know exactly what the question is.

At any time in any class you can access its private members if the class provides public access functions.

Here your class B is providing once-only set-access via its constructor, and that is what A is doing.

The constructor in B that takes two integers is public.

cougar autumn
December 24th, 2001, 07:39 PM
Please pay attention to the code beneath '>>>>>>>>>>>>>>>>>>>>>>>>',



#include "stdafx.h"

#include <iostream.h>

class B
{
public:
B(){};
B(int i, int j);
void printb();
private:
int a , b;
};

B::B(int i,int j)
{
a=i;
b=j;
}

void B::printb()
{
cout<<"a="<<a<<",b="<<b<<endl;
}

class A
{
public:
A(){};
A(int i, int j);
void printa();
private:
B b;
};


//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//pay close attention to this constructor, please, and here are the problem
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

A::A(int i,int j)
{
b.a=i;
b.b=j;
b::

}

void A::printa()
{
b.printb();
}


void main()
{
A m(7,9);
m.printa();
}



the following the debug result.

--------------------Configuration: we - Win32 Debug--------------------
Compiling...
we.cpp
K:\project04\we\we.cpp(43) : error C2248: 'a' : cannot access private member declared in class 'B'
K:\project04\we\we.cpp(15) : see declaration of 'a'
K:\project04\we\we.cpp(44) : error C2248: 'b' : cannot access private member declared in class 'B'
K:\project04\we\we.cpp(15) : see declaration of 'b'
Error executing cl.exe.

we.exe - 2 error(s), 0 warning(s)


I tried another way,
Instead of
A::A(int i,int j)
{
b.a=i;
b.b=j;

}

I write

A::A(int i,int j) :b(i,j)
{

}

and it works, My question is: what is the special magic the symbol : has?


Thank you in advance.




VC++ developer

Paul McKenzie
December 24th, 2001, 10:21 PM
I don't see any magic.

You are calling the parent class constructor when you use the initialization list. The constructor for B(int, int) is public. You provided it and made it public, so there is nothing stopping you from constructing it that way.

The other way, you are trying to access the members directly, but they are private in the B class. Except for the class itself and friends, no other class can access the private members. You thought you could make 'a' and 'b' private and access them directly from another class?

Regards,

Paul McKenzie

NMTop40
December 25th, 2001, 05:05 AM
hey that's what i just said.

and he wasn't asking you - he was asking me.

Paul McKenzie
December 25th, 2001, 10:38 AM
I know, but he didn't seem convinced. Also, if it's posted on CodeGuru, he asks everybody looking at the message.

Regards,

Paul McKenzie

Beuwolf
December 27th, 2001, 03:56 PM
splendid job fellows :)
allow me , if u may, to clarify it a bit more:

the use of the :b(i,j) just called the class B constructor. you could call the constructor without the : in the class A constrcutor:

A(int i ,int j)
{
B(i,j);
}




hope its more understood now.

Paul McKenzie
December 27th, 2001, 10:42 PM
you could call the constructor without the : in the class A constrcutor

??

No you can't. All your code does is create a temporary B object that is immediately destroyed. It does not call the constructor of the class member "b".

Also, you must use the initialization list if you want to construct a member with a non-default constructor. You cannot call "b(i,j)", since class A's members, including b, have already been created by the time the first "{" is reached in the A constructor. This is why initialization lists exist -- so that you can construct members that do not have a default constructor, or you want to construct the member using a parameter list.

Regards,

Paul McKenzie

Beuwolf
December 28th, 2001, 07:03 AM
Thanks Paul, you are right ofcourse.
my mistake!