• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 552
  • Last Modified:

How to instantiate class within a class?

Say I have a class ClassMain, and ClassMain needs to have a pointer to a ClassA. If I do the following:
ClassMain.h
#pragma once
#include "ClassA.h"

class ClassMain
{
public:
	ClassMain(void);
	ClassA *aPtr;
};

Open in new window

ClassMain.cpp
#include "StdAfx.h"
#include "ClassMain.h"

ClassMain::ClassMain(void)
{
	ClassA a;
	aPtr = &a;
}

Open in new window

My question is about creating the instance a of ClassA in the constructor of ClassMain. It looks like a will go out of scope the moment the constructor finishes executing, leaving my pointer aPtr pointing to an object that is all ready for garbage collection.

Is that a problem?

And while I'm at it I might as well ask how this would be done using an initialization list. Or is there an even better way of doing this?

(This will be an unmanaged code project. I like defining ClassA a at compile time rather than using a new statement.)
0
deleyd
Asked:
deleyd
4 Solutions
 
chaauCommented:
You have two options. One you have mentioned yourself: use an operator new() to create a new class. You will need to delete the pointer in the ClassMain destructor. This method is useful when there is no default constructor for the ClassA.
Imagine this situation:
class ClassA:
{
public:
  ClassA(int a) {_a = a;}
private:
  int _a;
};
For the class ClassA there is no default constructor. The only way to create the ClassA variable is to have an int parameter passed in.
In this case you instantiate the variable in your ClassMain constructor like this:
ClassMain::ClassMain(void)
{
	aPtr = new ClassA(5);
}

Open in new window

However, in your case, you can simply create an instance variable for the ClassA inside your ClassMain (this is by the way the second option), like this:
class ClassMain
{
public:
	ClassMain(void);
	ClassA a;
};

Open in new window

In this case ClassA will exist together with ClassMain, and will go in/out of scope with the ClassMain objects
0
 
deleydAuthor Commented:
Does
ClassA a;

Open in new window

go in the ClassMain.h file?

I thought of putting it there, but then wondered if that meant every one who did #include ClassMain.h would be instantiating an instance of ClassA?
0
 
chaauCommented:
If you put ClassA a; inside ClassMain, like this:
class ClassMain
{
public:
	ClassMain(void);
	ClassA a;
};

Open in new window

Then they would not. They will only instantiate the instance of ClassA only when they creat an instance of ClassMain
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
HooKooDooKuCommented:
You mentioned that ClassMain needs "a pointer".  Any particular reason for this?  If not, then what chaau has shown above is just fine... you're simply creating an instance of ClassA within ClassMain.

But by saying you "need a pointer" implies the ClassA object is coming from outside of ClassMain.  In that case, what you could do is have a pointer to a ClassA object defined in ClassMain, and initialize it via ClassMain constructors and member functions.

//ClassMain.h
class ClassA;    //Forward declaration... says the class will exist without giving details
class ClassMain
{
  private:
    ClassA* m_pA;  //Forward declaration allows us to define a pointer variable without details

  public:
    ClassMain();
    ClassMain( ClassA* );
}

//ClassMain.cpp
#include ClassMain.h
#include ClassA.h         //Order of these two doesn't mater

ClassMain::ClassMain()
{
    m_pA = NULL;
}

ClassMain::ClassMain( ClassA* pA )
{
    m_pA = pA;
}

Open in new window


OF course you have to be careful regarding the life cycle of ClassMain and ClassA.  If you create a ClassA object and a ClassMain object, and then pass a pointer to the ClassA object to ClassMain, and ClassA becomes invalid (such as goes out of scope), then the pointer in ClassMain becomes invalid.  This is where creating the ClassA object within ClassMain can be safer, because that way as the programmer of ClassMain, you control the life cycle of ClassA.  Otherwise, passing a pointer into ClassMain means that someone else could use your ClassMain inappropriately.
0
 
deleydAuthor Commented:
If I instantiate ClassA in my ClassMain.h file, is there a problem with everyone who does #include "ClassMain.h" at the top of their file ends up instantiating another instance of ClassA, a side effect they don't necessarily want?
#pragma once
#include "ClassA.h"

class ClassMain
{
public:
	ClassMain(void);
	ClassA a;
};

Open in new window

0
 
sarabandeCommented:
you don't instantiate a member variable in the header file but you only declare it.

the member variable a is instantiated when some one does

ClassMain m;

Open in new window



or

ClassMain pm = new ClassMain();

Open in new window


both statements would instantiate a object of class ClassMain and with that also a object of ClassA which could be accessed by m.a in the first case and by pm->a in the pointer case.

Note, if you would make the member a private member (like HooKooDooKu showed) only member functions of ClassMain could be access the member a.

Sara
0
 
deleydAuthor Commented:
I'm starting to get it. Just including ClassMain.h doesn't instantiate an an instance of that class, it just gives information about the class in case anyone's interested. Creating the instance of ClassMain gives me variable a which is an instance of ClassA, and I don't have to do anything in the constructor of ClassMain to create an instance of ClassA

In C# this wouldn't work because a is never created.:
    class ClassMain
    {
        ClassA a;

        public void Run()
        {
            a.Test();
        }
    }

Open in new window

But in C++ this works just fine:
class ClassMain
{
public:
  ClassA a;

  void Run()
  {
    a.Test();
  }
};

Open in new window

0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now