use of member functions in constructors

S

Shailesh Humbad

Here is my queue class. Is it okay to call a private member function
of the class from the constructor?

// custom constructor
MyQueue::MyQueue(unsigned long lInitialSize,
unsigned long lInitialSizeAlignment)
{
this->pbQueue = NULL;
this->InitializeClass(lInitialSize, lInitialSizeAlignment);
}
// default constructor
MyQueue::MyQueue()
{
this->pbQueue = NULL;
this->InitializeClass(DEFAULT_SIZE, DEFAULT_SIZE_ALIGNMENT);
}

// handles construction task
void
MyQueue::InitializeClass(unsigned long lInitialSize,
unsigned long lInitialSizeAlignment)
{
if(pbQueue != NULL)
{
return;
}
if(lInitialSize == 0)
{
lInitialSize = DEFAULT_SIZE;
}
if(lInitialSizeAlignment = 0)
{
lInitialSizeAlignment = DEFAULT_SIZE_ALIGNMENT;
}

this->pbQueue = (LPBYTE) HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY,
lInitialSize);
CheckAllocation(this->pbQueue, 1);

this->pbFront = this->pbQueue;
this->lQueueLength = 0;
this->lQueueMax = lInitialSize;
this->lSizeAlignment = lInitialSizeAlignment;
}
 
J

JKop

Is it okay to call a private member function
of the class from the constructor?


Yes. You can call private member functions of a class from:

A) Within member functions of the class (not necessarily of the current
object). This includes from within any constructors and destructor.

B) Friend functions and friend classes' member functions.


-JKop
 
S

Sharad Kala

Shailesh Humbad said:
Here is my queue class. Is it okay to call a private member function
of the class from the constructor?

Yes. In fact this is a way to share common functionality between overloaded
constructors. Also note that virtuality is not achieved inside constructors.

Sharad
 
S

Shailesh Humbad

Sharad said:
Yes. In fact this is a way to share common functionality between overloaded
constructors. Also note that virtuality is not achieved inside constructors.

Sharad

I just found a bug because I had done the following in my constructor

MyObject::MyObject() {
// may cause bugs later, i.e. poor style
ZeroMemory(this, sizeof(this));
...
}

It was working fine until I added an STL list to MyObject. Then I got
an access violation in a begin() function call in an unrelated piece
of code. Eventually, I tracked it down and realized all the internal
pointers of the STL list were being reset to zero (memory leak). This
bug just scared me a little to access the object being constructed
from within the constructor, which is why I asked the question. So my
question is about good style as well.
 
C

Catalin Pitis

Shailesh Humbad said:
I just found a bug because I had done the following in my constructor

MyObject::MyObject() {
// may cause bugs later, i.e. poor style
ZeroMemory(this, sizeof(this));
...
}

It was working fine until I added an STL list to MyObject. Then I got an
access violation in a begin() function call in an unrelated piece of code.
Eventually, I tracked it down and realized all the internal pointers of
the STL list were being reset to zero (memory leak). This bug just scared
me a little to access the object being constructed from within the
constructor, which is why I asked the question. So my question is about
good style as well.

Don't you ever ever do that again :) Initialize the members from the
initialization list of the constructor. The construction mechanism can help
a lot, if you know it well.

Catalin
 
J

JKop

MyObject::MyObject() {
// may cause bugs later, i.e. poor style
ZeroMemory(this, sizeof(this));
...
}


S a t a n l i v e s!


If you have:


struct AggregatePOD
{
int k;
char* p_r;
};


and you want to create a "zero-initialized" object of it, then:


template<class T>
class ValueInitialized : virtual public T
{
public:
ValueInitialized() : T() {}
};

int main()
{
ValueInitialized<AggregatePOD> monkey;

//Another method you'll commonly see:

AggregatePOD ape = AggregatePOD();
}


As for having a class which has member objects which you want to be value
initialized:

#include <string>

class NonAggregateNonPOD
{
std::string blah;
int k;
void* address;

public:
NonAggregateNonPOD() : blah(), k(), address() {}
//The above is how it's done
//ie. in an initializer list
};


Never EVER do the likes of what you did, ie. calling ZeroMemory in the
constructor. (BTW, "ZeroMemory" is a macro for "memset" ). You also would
mess up the pointer to the vtable if you had any virtual functions! (Also,
in my example, you'd be messing up all the memory allocation data in the
std::string object).


-JKop
 
H

Howard

I just found a bug because I had done the following in my constructor

MyObject::MyObject() {
// may cause bugs later, i.e. poor style
ZeroMemory(this, sizeof(this));
...

More than bad style. It doesn't do what you're thinking. Since "this" is a
pointer, sizeof(this) is the size of a pointer, not the size of the current
object.

-Howard
 
R

Ron Natalie

Howard said:
More than bad style. It doesn't do what you're thinking. Since "this" is a
pointer, sizeof(this) is the size of a pointer, not the size of the current
object.
Even sizeof(*this) would be a bad idea. Nothing says that
writing zeros all over a class is a good way to initialized
it (even if it's POD).
 
O

Old Wolf

Shailesh Humbad said:
I just found a bug because I had done the following in my constructor

MyObject::MyObject() {
// may cause bugs later, i.e. poor style
ZeroMemory(this, sizeof(this));

'this' is a pointer so you are zeroing four bytes (or whatever),
I think you meant: sizeof *this

This is nothing to do with privateness or constructors, you
would get the same problem if you did it from a different
member function, or from anywhere else, eg:

MyObject m;
ZeroMemory(&m, sizeof m);

because the object may contain information other than just the
variables you've declared (eg. a virtual dispatch table, memory
allocation info, ...)
 
S

Shailesh Humbad

JKop said:
S a t a n l i v e s!


If you have:


struct AggregatePOD
{
int k;
char* p_r;
};


and you want to create a "zero-initialized" object of it, then:


template<class T>
class ValueInitialized : virtual public T
{
public:
ValueInitialized() : T() {}
};

int main()
{
ValueInitialized<AggregatePOD> monkey;

//Another method you'll commonly see:

AggregatePOD ape = AggregatePOD();
}


As for having a class which has member objects which you want to be value
initialized:

#include <string>

class NonAggregateNonPOD
{
std::string blah;
int k;
void* address;

public:
NonAggregateNonPOD() : blah(), k(), address() {}
//The above is how it's done
//ie. in an initializer list
};


Never EVER do the likes of what you did, ie. calling ZeroMemory in the
constructor. (BTW, "ZeroMemory" is a macro for "memset" ). You also would
mess up the pointer to the vtable if you had any virtual functions! (Also,
in my example, you'd be messing up all the memory allocation data in the
std::string object).


-JKop


Yeah, I didn't have sizeof(this), I had:

ZeroMemory(this, sizeof(class MyObject));

It did what I wanted it to do since my object only had ints, int
arrays, pointers, and some non-virtual functions. I just wanted to
save time typing out the 25 or so members. My code was mostly C until
recently, so that was just a vestige of the assumptions I was
operating under at that time.

I just started with templates, and I don't really understand your code
above very much. I don't know what POD is. It's okay though, since
my project doesn't have much use for templated objects, inheritance,
or template initializers at this moment.
 
J

JKop

Shailesh Humbad posted:
I just wanted to save time typing out the 25 or so members.


Nor does anyone else. That's why we do:


MyObject blah = {};

MyObject blah = MyObject();

ValueInitialized<MyObject> blah;


-JKop
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,458
Latest member
Chris#

Latest Threads

Top