Information on Non-default member class whose argument is another class

Hello All,
I have 2 sets of code. Once compiles and the other doesn't. But I don't understand why. Can somebody please help? I started coding cpp just recently. Please excuse me if I am missing anything obvious.

Code which compiles :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

class classB
{
	public:
		//ctor
		classB(){}

};

class classC
{
	public:
		classB *mb;

		classC()
        {
			std::cout << "Called default" << std::endl;
        }

		//ctor
	 	classC(classB* x)
	 	{
			std::cout << "Called other" << std::endl;
			mb = x;
	 	}
};

class classA
{
	public:
		classB m_aB;
		classC m_aC;

		//ctor
		classA() : m_aC(&m_aB)
		{}
		
};

int main()
{
	classA cA;
	return 0;
}


Code which does not compile :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>

class classB
{
	public:
		//ctor
		classB(){}

};

class classC
{
	public:
		classB *mb;

		classC()
        {
			std::cout << "Called default" << std::endl;
        }

		//ctor
	 	classC(classB* x)
	 	{
			std::cout << "Called other" << std::endl;
			mb = x;
	 	}
};

class classA
{
	public:
		classB m_aB;
		classC m_aC(&m_aB);

		//ctor
		classA(){}
		
};

int main()
{
	classA cA;
	return 0;
}

The error is

g++ test.cpp -o test
test.cpp:33:15: error: expected identifier before ‘&’ token


I don't understand why is it complaining because the identifier is define in line ~32.

Thanks in advance.
Tony
Last edited on
That's not how you initialise a data member. You need to use an initialisation list in the constructor:

EDIT: THERE IS AN ERROR IN THE CODE BELOW. PLEASE CHECK MY POST LOWER DOWN IN THE THREAD FOR THE CORRECT CODE.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class classA
{
	public:

		classB m_aB;
		classC m_aC(&m_aB);

		//ctor
		classA() :
		  m_aC(&m_aB)
		{}
		
};

You should do this in your creator for classC as well, rather than assigning a value to mb in the body of the constructor.

Edit: What you originally wrote would be interpreted as the declaration of a method called m_aC, with an argument called m_aB that is a reference. The compiler expects there to be a type before the argument, in a method declaration.
Last edited on
to declare argument as a reference you should use following syntax: function_name(type& variable_name)
Variable name is optional in declarations.
You have misplaced & and have used variable name instead of type
Hello MikeyBoy,
Thank you for the information. Changing Initialisation on m_aC from
1)
classC m_aC
to
classC m_aC
gives the error

g++ test_compile.cpp -o test
test_compile.cpp:33:15: error: expected identifier before ‘&’ token
test_compile.cpp: In constructor ‘classA::classA()’:
test_compile.cpp:36:14: error: class ‘classA’ does not have any field named ‘m_aC’


2) My intention is to pass pointer to m_aB as argument to m_aC (which can be used to call methods of m_aB). My understanding is when I create an object

classA cA;

The memory is created for the class from the top to bottom. So in the case of

1
2
3
public:
		classB m_aB;
		classC m_aC(&m_aB);


the compiler should already have the memory and variable "m_aB" instantiated and known. Isn't it true?

3)I also thought when a class instance is instantiated irrespective as a member class or as a standalone class, the constructor would be called. So in the following code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>

class classB
{
	public:
		//ctor
		classB(){}

};

class classC
{
	public:
		classB *mb;

		//ctor
	 	classC(classB* x)
	 	{
			std::cout << "Called other" << std::endl;
			mb = x;
	 	}
};

class classA
{
	public:
		classB m_aB;
		classC m_aC;

		//ctor
		classA() : m_aC(&m_aB)
		{}
		
};

int main()
{
	classA cA;
	return 0;
}

I expected the
classC m_aC;
line ~28 to fail because the classC does not have a constructor of type
classC(){}
But it compiles fine.
I am by default a C programmer. So I might be missing something specific to cpp :). Any thoughts?
Last edited on
Hi MiiNiPaa,
Thank you for the information. My intention is to pass pointer(not reference) to the class instance m_aB. I thought when I instantiate instance of classA member instance of classB will be created. Isnt that the case? If not when would the memory for classB be allocated?
Ooops, sorry, in the code I posted there was an error. It should be:

1
2
3
4
5
6
7
8
9
10
11
12
13
class classA
{
	public:

		classB m_aB;
		classC m_aC; // CANNOT initialise m_aC here.

		//ctor
		classA() :
		  m_aC(&m_aB) // Initialise m_aC in the constructor, using an initialisation list
		{}
		
};

My point is that in line 33 of your original code, you CANNOT initialise m_aC. It's just not legal C++. You have to do it in the constructor - preferably using an initialisation list, like I've shown you.

My apologies for the mistake.
Last edited on
Hi MikeyBoy,
No apologies required. Any suggestions are welcome. I am grateful for your help.

I am still a bit confiused, what happens when we do
classC m_aC;? In my second post(first post today) I don't have a default constructor for class C. But it still compiles.
Cheers,
If you don't have any constructors defined at all for a class, then the compiler will create a default constructor implicitly. This constructor will perform no initialisation, and have an empty body - in other words, it will do nothing.

This is necessary because, otherwise, it would be impossible to instantiate an object of that class.

Edit: See, for example:

http://tinyurl.com/kzuw3af

(Link goes to IBM site).
Last edited on
I think I understand it now. A class will only call the default constructor of member classes (how ever it is called), unless the modified constructor is given in the initialisation list of the main class. Am I right?
Yes exactly. Because the initialisation list is the only way to pass any arguments to the constructor of a base class or of a member object. And if you're not passing any arguments, then it has to be the default constructor.
Last edited on
Thank you MikeyBoy. Marking this forum as solved.

Cheers,
Tony
You're welcome!
Topic archived. No new replies allowed.