Access a Class Object Created in a Constructor

I have a class I'll call class_A that creates an instance another class let's say class_B when it's constructor is called. The issue I'm having is that when I create and instance of class_A I'm having trouble accessing functions of the class_B that should be associated with it.

Each class has it's own class and header file and I've put in the #include for each. I'm also using a global class pointer.


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
class_A.cpp

class_B* B;

class_A::class_A(void)
{
	
	B = new class_B(this);
}

class_B.cpp

class_A* A;

class_B::class_B(class_A* this_A)
{	
	A = this_A;
}

void class_B::class_B_method()
{
	//code here
}


main.cpp

void _tmain(int argc, _TCHAR* argv[])
{
	//create a new instance of class_A which also creates a new instance of class_B
	class_A* new_A = new class_A();

	//the following code is not accurate
	new_A->B->class_B_method();

}
Last edited on
Going to take a shot. Not sure all of what you are doing but it looks like class_A.cpp has a global B pointer that gets set in the A constructor. In class_B.cpp you have a global A pointer that gets set in the B constructor. But in the main.cpp new_A tries to reference B but it looks as if B is not a member of A but a global so new_A->B wont work. B would have to be a member of the A class for that to work.
Do you have a member B in the class_A?
Is B not a member of class_A when it's initialized in the class_A constructor?
No, unless you have in your class_A:
1
2
3
4
class class_A {
    public:
       class_B *B;
}

Otherwise your are just setting a global variable.

Alright that makes sense, and I can now see it in my main but I'm still unable to access the members of the class_B object. And other methods in class_A cannot utilize the object. My IDE reports them as "expression must have pointer-to-class type" That's the reason I used a global variable to begin with.

I appreciate the help you've given me so far. Any more insight would be great, I'll continue to research off of what you've said so far. Somehow I've got to make the class object in my header reachable by other methods in my class and reference the methods of the object once it's been initialized.
Why do you have to access B from inside of A? With the global you can just access B functions by just using the B pointer. Not that I recommend using a global.
Last edited on
The idea is that class B is an object found inside of class A, so each time I create an instance of class A, there will be a unique instance of class B created. Am I approaching this wrong for c++? This concept makes sense to me in java or c#.
Is the only person that wants to talk to class_B, class_A?
If yes, then you can define class_B all in side of class_A and make class_B a member. If can be created in the constructor or a new in the constructor.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class class_A {
    public:
        // Define B
        class class_B {
               public:
                  class_B(){};
        };

        class_A() {};

    private:
        class_B B;
        // or 
        class_B *ptrB;
};

If no, then you have to define class_B and class_A and include class_B.h in the class_A.h file.
In either every case class_A would have a unique instance of class_B.
It is object composition where you combine simple objects or data types into more complex ones.
http://www.learncpp.com/cpp-tutorial/102-composition/
Like a computer is made up of a CPU, disks, keyboard, screen and etc... The class computer is made up of all of the other classes CPU, disks, etc...
In C++ class instances are values (not references)

So what you want is actually the default behaviour in C++ (no special stuff required)

1
2
3
4
5
6
7
class A
{
private:
  B b;  // when you create an A then a new instance of B is created (this is a value not a reference)
public:
  ...
};


Also if you use the new keyword to create the object, then your reference to the object needs to be a pointer, not a name.

1
2
3
4
5
MyObject o = new MyObject() ; // will fail; probably won't even compile...?
MyObject *p = new MyObject() ; // will work; returns pointer to a MyObject created with default constructor
MyObject n ; // will also work; calls default MyObject constructor
p->method() ; // calls member function MyObject::method() for instance at *p
n.method() ; // calls member function MyObject::method() for instance named n 
Last edited on
MyObject n(); That's a function declaration. It returns a MyObject and receives nothing.
MyObject n; An object constructed with the default constructor.
(@ne555) durr durr careless durr durr fixed thank you
Thanks for the link to composition. I decided to recreate that using .h an .cpp files to work on my c++ skills. It compiled successfully but now after modeling my project after it I am still running into a an error while compiling. There are more parts to the project but I'm focusing on the top level for now until I have a more firm grasp on my errors.

Below is my source. The error occurs in Room.h on line 11 where I declare "Thermostat thermostat_in_room;"


room.h(11): error C2146: syntax error : missing ';' before identifier 'thermostat_in_room'
room.h(11): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
room.h(11): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int



Room.h
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
#pragma once
#include <iostream>
#include <string>
#include "Thermostat.h"

using namespace std;

class Room
{
private:
	Thermostat thermostat_in_room;
	std::string name;
	int temperature;

public:
	Room(std::string new_Name);
	~Room(void);
	
	// return room name
	std::string Get_name(void);
	
	// return room temperature
	int Get_temp(void);
	
	// modify room temperature
	void Change_temp(int);
};


Room.cpp
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
#include "StdAfx.h"
#include "Room.h"

Room::Room(std::string new_Name)
	: thermostat_in_room()
{
	temperature = 65;
	name = new_Name;
}


Room::~Room(void)
{
}


// return room name
std::string Room::Get_name(void)
{
	return name;
}


// return room temperature
int Room::Get_temp(void)
{
	return temperature;
}


// modify room temperature
void Room::Change_temp(int Delta_temp)
{
	temperature = temperature + Delta_temp;
	thermostat_in_room.Check_temp();
}


Thermostat.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include <iostream>
#include <string>
#include "Room.h"
#include "AirConditioner.h"

using namespace std;

class Thermostat
{
public:
	Thermostat();
	~Thermostat(void);
	std::string name;
	int setting;
	// return thermostat name
	std::string Get_name(void);
	// modify thermostat setting
	void Change_setting(int);
	void Check_temp(void);
};


Thermostat.cpp
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 "StdAfx.h"
#include "Thermostat.h"

Thermostat::Thermostat()
{
	//location = this_Room;
	//what_it_controls = new AirConditioner(this_Room);
	//name = location->Get_name() + "_Thermostat";
	setting = 65;
	
}


Thermostat::~Thermostat(void)
{
}


// return thermostat name
std::string Thermostat::Get_name(void)
{
	return name;
}


// modify thermostat setting
void Thermostat::Change_setting(int New_setting)
{
	setting = New_setting;
	this->Check_temp();
}

// check temperature
void Thermostat::Check_temp(void)
{
	/*if(location->Get_temp() > setting)
	{
		what_it_controls->Turn_on();
	}
	else
	{
		what_it_controls->Turn_off();
	}*/
}
Last edited on
There is no need for Thermostat.h to include Room.h
http://cplusplus.com/forum/articles/10627/ (point 4)
Thanks for the link ne555, telling me what I needed to do is one thing, showing me why is much better!

Removing the Room.h include does allow everything to compile. Which brings me to my next question, without including Room.h in Thermostat.h will I be able to create a pointer back to the Room object from Thermostat? I need to do this for some recursive calls. I'm going to see what I can figure out, but at this point the composition and includes make sense.
I got ahead of myself. ne555 your link explained how to do this as well by using forward declared dependencies. Thanks again.
I know I'm close, and I do wish I could figure this out by just reading the information I've found but so far no such luck. Maybe I'll get it before someone points it out to me, but I doubt it ;-)

The error occurs on line 35 of thermostat.cpp when I attempt to use my pointer to the room to call a function of the room and get "use of undefined type"

Here is my code:

Room.h
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
#pragma once
#ifndef Room_H
#define Room_H
#include <iostream>
#include <string>
#include "Thermostat.h"

using namespace std;

class Room
{
private:
	Thermostat thermostat_in_room;
	std::string name;
	int temperature;

public:
	//constructor
	Room(std::string new_Name);

	//destructor
	~Room(void);
	
	// return room name
	std::string Get_name(void);
	
	// return room temperature
	int Get_temp(void);
	
	// modify room temperature
	void Change_temp(int);
};
#endif 


Room.cpp
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
#include "StdAfx.h"
#include "Room.h"

Room::Room(std::string new_Name)
	: thermostat_in_room(this)
{
	temperature = 65;
	name = new_Name;
}


Room::~Room(void)
{
}


// return room name
std::string Room::Get_name(void)
{
	return name;
}


// return room temperature
int Room::Get_temp(void)
{
	return temperature;
}


// modify room temperature
void Room::Change_temp(int Delta_temp)
{
	temperature = temperature + Delta_temp;
	thermostat_in_room.Check_temp();
}


Thermostat.h
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
#pragma once
#include <iostream>
#include <string>
#include "AirConditioner.h"

using namespace std;

class Room;

class Thermostat
{
private:
	std::string name;
	int setting;
	Room *location;
	AirConditioner what_it_controls;

public:
	//constructor
	Thermostat(Room*);

	//destructor
	~Thermostat(void);

	// return thermostat name
	std::string Get_name(void);

	// modify thermostat setting
	void Change_setting(int);

	// check the room temperature and activate Air Conditioner
	void Check_temp(void);
};


Thermostat.cpp
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
#include "StdAfx.h"
#include "Thermostat.h"

Thermostat::Thermostat(Room* this_Room)
	: what_it_controls(this_Room)
{
	location = this_Room;
	setting = 65;
	
}


Thermostat::~Thermostat(void)
{
}


// return thermostat name
std::string Thermostat::Get_name(void)
{
	return name;
}


// modify thermostat setting
void Thermostat::Change_setting(int New_setting)
{
	setting = New_setting;
	this->Check_temp();
}

// check temperature
void Thermostat::Check_temp(void)
{
	if(location->Get_temp() > setting)
	{
		what_it_controls.Turn_on();
	}
	else
	{
		what_it_controls.Turn_off();
	}
}


AirConditioner.h
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
#pragma once
#include <iostream>
#include <string>

class Room;
class Thermostat;

class AirConditioner
{
private:
	Room* Room_location;
	bool state;
	std::string name;

public:
	//constructor
	AirConditioner(Room*);

	//desctructor
	~AirConditioner(void);

	// return air conditioner name
	std::string Get_name(void);

	// turn air conditioner on and lower room temp 1 degree
	void Turn_on(void);

	// turn air conditioner off
	void Turn_off(void);
};


AirConditioner.cpp
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
46
47
48
49
#include "StdAfx.h"
#include "AirConditioner.h"
#include <stdio.h>
#define FALSE (0)
#define TRUE (1)

AirConditioner::AirConditioner(Room* this_Room)
{
	Room_location = this_Room;
	//name = Room_location->Get_name() + "_AC";
	state = FALSE;
}


AirConditioner::~AirConditioner(void)
{
}


// return air conditioner name
std::string AirConditioner::Get_name(void)
{
	return name;
}


void AirConditioner::Turn_on(void)
{
	if(state == FALSE)
	{
		state = TRUE;
	}
	//printf ("%s \n", "Room " + Room_location->Get_name() + " AC on");
	//printf ("%s \n", "Temperature: " + Room_location->Get_temp());
	printf ("%s \n", "TEST");
//	Room_location->Change_temp(-1);
}


void AirConditioner::Turn_off(void)
{
	if(state == TRUE)
	{
		state = FALSE;
	}
	//printf ("%s \n", "Room " + Room_location->Get_name() + " AC off");
	//printf ("%s \n", "Temperature: " + Room_location->Get_temp());
	printf ("%s \n", "TEST");
}
Last edited on
Topic archived. No new replies allowed.