473,324 Members | 2,193 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

Why is the Base class Constructor getting called twice

Hello all...

In my code below, the Notify Constructor and Destructor is getting
called twice and it appears that a new Notify object is created on the
2nd call. The 2nd call is caused by this line below: pNotify = new
EMAILnotify; that lives in the Notification Constructor.

One theory is that the Notify base class is not completely constructed
prior to using it in the Notification Constructor code: pNotify = new
EMAILnotify;

All the code below can be pasted into a *.cpp module and will compile
and run with a VC++6.0 compiler.

Thanks in advance for any clues as to why?

************************************************** ************
#include <iostream>
#include <string>

using namespace std;

class Notify
{
public:
Notify(void){ cout << "Constructing Notify: " << this << endl; }
virtual ~Notify(void){ cout << "Destructing Notify: " << this <<
endl; }
virtual void Send() = 0;
};
class Notification : public Notify
{
public:
Notification(void){}
Notification(string sNotifyType);
virtual ~Notification(void);
void Send(){ pNotify->Send(); }
private:
Notify* pNotify;

};
class EMAILnotify : public Notify
{
public:
EMAILnotify(void){}
virtual ~EMAILnotify(void){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification::Notification(string sNotifyType)
{
if(sNotifyType == "EMAIL")
pNotify = new EMAILnotify; // Causes 2nd Constructor call
}
Notification::~Notification(void)
{
if( NULL != pNotify )
delete pNotify;
}

void main()
{
Notification* pNotification = new Notification("EMAIL");
pNotification->Send();
delete pNotification;
}
Jul 22 '05 #1
6 3649
On 10 Dec 2003 10:20:24 -0800, aq*****@seanet.com (Robert) wrote:
In my code below, the Notify Constructor and Destructor is getting
called twice and it appears that a new Notify object is created on the
2nd call. The 2nd call is caused by this line below: pNotify = new
EMAILnotify; that lives in the Notification Constructor.
Class Notification derives from Notify. The calling sequence is:
(1) create a Notification object, which executes the Notify constructor,
and then (2) executes the Notification constructor body, which (3)
executes pNotify = new EMAILnotify, which (4) creates an EMAILnotify
object, where EMAILnotify is derived from Notify, so that this creation
(5) executes the Notify constructor for the EMAILnotify object, and (6)
proceeds to execute the EMAILnotify constructor body.

...

************************************************* *************
#include <iostream>
#include <string>

using namespace std;

class Notify
This is a bad name for a class. A class doesn't "do" anything,
unless it's a functor class. Which this isn't.

{
public:
Notify(void){ cout << "Constructing Notify: " << this << endl; }
Style.
'void' as an argument list is a C'ism which you'd better forget.
virtual ~Notify(void){ cout << "Destructing Notify: " << this <<
endl; }
virtual void Send() = 0;
};
Style.
At least one empty line between class declarations is a good idea.
class Notification : public Notify
{
public:
Notification(void){}
Notification(string sNotifyType);
virtual ~Notification(void);
void Send(){ pNotify->Send(); }
private:
Notify* pNotify;

};
Style.
The definitions of the Notification member functions should appear
here, before anything more. One "place" per class in the code.

Design.
Having a pNotify member doesn't seem to serve any useful purpose.
Most probably you have tried to implement too much in one class.
class EMAILnotify : public Notify
{
public:
EMAILnotify(void){}
virtual ~EMAILnotify(void){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification::Notification(string sNotifyType)
{
if(sNotifyType == "EMAIL")
Design.
Don't identify types by strings (in general). Use symbolic constants
if you absolutely have to. But even more to the point: don't identify
types by data unless you really Really REALLY have to.

pNotify = new EMAILnotify; // Causes 2nd Constructor call
}
Notification::~Notification(void)
{
if( NULL != pNotify )
Coding.
No need to check for NULL.

delete pNotify;
}

void main()
C++ standard.
'void main' is not allowed. This is not a valid standard C++ program.

{
Notification* pNotification = new Notification("EMAIL");
pNotification->Send();
delete pNotification;
Style.
The above is not exception safe in any sense. Use a std::auto_ptr.

}


Jul 22 '05 #2
Robert wrote:
....

Thanks in advance for any clues as to why?
because you inherit notify in two different classes and instantiate both
classes.

************************************************** ************
#include <iostream>
#include <string>

using namespace std;

class Notify
{
public:
Notify(void){ cout << "Constructing Notify: " << this << endl; }
virtual ~Notify(void){ cout << "Destructing Notify: " << this <<
endl; }
virtual void Send() = 0;
};
class Notification : public Notify
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inherit 1
{
public:
Notification(void){}
Notification(string sNotifyType);
virtual ~Notification(void);
void Send(){ pNotify->Send(); }
private:
Notify* pNotify;

};
class EMAILnotify : public Notify

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inherit 2

{
public:
EMAILnotify(void){} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ : Notify() implicitly constructed here

virtual ~EMAILnotify(void){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification::Notification(string sNotifyType) : Notify() // implicit construct of Notify

{
if(sNotifyType == "EMAIL")
pNotify = new EMAILnotify; // Causes 2nd Constructor call // Making second Notify here
}
Notification::~Notification(void)
{
if( NULL != pNotify )
delete pNotify;
}

void main()
must use int - not void....

int main()
{
Notification* pNotification = new Notification("EMAIL");
pNotification->Send();
delete pNotification;
}


Jul 22 '05 #3
Robert wrote:

Hello all...

In my code below, the Notify Constructor and Destructor is getting
called twice and it appears that a new Notify object is created on the
2nd call. The 2nd call is caused by this line below: pNotify = new
EMAILnotify; that lives in the Notification Constructor.

One theory is that the Notify base class is not completely constructed
prior to using it in the Notification Constructor code: pNotify = new
EMAILnotify;


The ctor is called twice because you create 2 Notify objects.

Object 1:
Notification* pNotification = new Notification("EMAIL");

Object 2: inside the ctor of Notification
pNotify = new EMAILnotify;

It seems you have a design error. From what I can see, you don't
want a Notification object to be a Notify object at the same time.
A Notification object *contains* a Notify object, but that's it. A
Notification is not a Notify on its own.

class Notification
{
....

Notify* pNotify;
};
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #4
al***@start.no (Alf P. Steinbach) wrote in message news:<3f****************@News.CIS.DFN.DE>...
On 10 Dec 2003 10:20:24 -0800, aq*****@seanet.com (Robert) wrote:
In my code below, the Notify Constructor and Destructor is getting
called twice and it appears that a new Notify object is created on the
2nd call. The 2nd call is caused by this line below: pNotify = new
EMAILnotify; that lives in the Notification Constructor.
Class Notification derives from Notify. The calling sequence is:
(1) create a Notification object, which executes the Notify constructor,
and then (2) executes the Notification constructor body, which (3)
executes pNotify = new EMAILnotify, which (4) creates an EMAILnotify
object, where EMAILnotify is derived from Notify, so that this creation
(5) executes the Notify constructor for the EMAILnotify object, and (6)
proceeds to execute the EMAILnotify constructor body.


Thanks for all the information and tips...
...

************************************************* *************
#include <iostream>
#include <string>

using namespace std;

class Notify


This is a bad name for a class. A class doesn't "do" anything,
unless it's a functor class. Which this isn't.


Agreed!...
{
public:
Notify(void){ cout << "Constructing Notify: " << this << endl; }


Style.
'void' as an argument list is a C'ism which you'd better forget.


Agreed!, that's what I get for cutting and pasting sample code.
virtual ~Notify(void){ cout << "Destructing Notify: " << this <<
endl; }
virtual void Send() = 0;
};
Style.
At least one empty line between class declarations is a good idea.


This was a post, need to keep it short.
class Notification : public Notify
{
public:
Notification(void){}
Notification(string sNotifyType);
virtual ~Notification(void);
void Send(){ pNotify->Send(); }
private:
Notify* pNotify;

};
Style.
The definitions of the Notification member functions should appear
here, before anything more. One "place" per class in the code.


Again, this was a post, the real code is in separate modules.
Design.
Having a pNotify member doesn't seem to serve any useful purpose.
Most probably you have tried to implement too much in one class.

pNotify as a member is vital in supporting the strategy pattern.
Please correct me if I'm wrong.
class EMAILnotify : public Notify
{
public:
EMAILnotify(void){}
virtual ~EMAILnotify(void){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification::Notification(string sNotifyType)
{
if(sNotifyType == "EMAIL")


Design.
Don't identify types by strings (in general). Use symbolic constants
if you absolutely have to. But even more to the point: don't identify
types by data unless you really Really REALLY have to.


Agreed!, but then how would I identify a type at run time via
polymorphism?
pNotify = new EMAILnotify; // Causes 2nd Constructor call
}
Notification::~Notification(void)
{
if( NULL != pNotify )


Coding.
No need to check for NULL.


Yep!
delete pNotify;
}

void main()


C++ standard.
'void main' is not allowed. This is not a valid standard C++ program.


When I test sample code, no need to worry about Standards that would
not cause bugs...
{
Notification* pNotification = new Notification("EMAIL");
pNotification->Send();
delete pNotification;


Style.
The above is not exception safe in any sense. Use a std::auto_ptr.


This is sample code, in the real program it is wrapped in a
try{}catch{}
}

Thanks again for your tips...

--Robert
Jul 22 '05 #5
Robert wrote:
Design.
Don't identify types by strings (in general). Use symbolic constants
if you absolutely have to. But even more to the point: don't identify
types by data unless you really Really REALLY have to.

Agreed!, but then how would I identify a type at run time via
polymorphism?


By not identifying them at all.
In your case: Why pass a string identifying the type of notify
when you can pass a Notify object at the same time.

class Notification
{
public:
Notification( Notify* pNotify ) : m_pNotify( pNotify ) {}
~Notification() { delete pNotify; }
void Send() { m_pNotify->Send(); }
...

private:
Notify* m_pNotify;
};

class Notify
{
public:
virtual ~Notify();
...
virtual void Send() = 0;
};

class EMailNotify : public Notify
{
public:
EMailNotify( std::string& To ) : m_To( To ) {}
...
virtual void Send() { std::cout << "Sending EMail to " << m_To << std::endl;

private:
std::string m_To;
};

class SnailMailNotify : public Notify
{
public:
SnailMailNotify( std::String& To ) : m_To( To ) {}
...
virtual void Send() { std::cout << "Sending snail mail to " << m_To << std::endl;

private:
std::string m_To;
};
int main()
{
Notification* pEvent1 = new Notification( new EmailNotification( "aq*****@seanet.com" ) );
Notification* pEvent2 = new Notification( new SnailMailNotify( "Robert" ) );

pEvent1->Send();
pEvent2->Send();

When I test sample code, no need to worry about Standards that would
not cause bugs...


If you post in this group and use void main() you will always get a reply
for that. Plain and simple: void main() is wrong. The fact that your
compiler allows you to use it is irrelevant. It is still wrong.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #6
jb
al***@start.no (Alf P. Steinbach) wrote in message news:<3f****************@News.CIS.DFN.DE>...
On 10 Dec 2003 10:20:24 -0800, aq*****@seanet.com (Robert) wrote:
In my code below, the Notify Constructor and Destructor is getting
called twice and it appears that a new Notify object is created on the
2nd call. The 2nd call is caused by this line below: pNotify = new
EMAILnotify; that lives in the Notification Constructor.


Class Notification derives from Notify. The calling sequence is:
(1) create a Notification object, which executes the Notify constructor,
and then (2) executes the Notification constructor body, which (3)
executes pNotify = new EMAILnotify, which (4) creates an EMAILnotify
object, where EMAILnotify is derived from Notify, so that this creation
(5) executes the Notify constructor for the EMAILnotify object, and (6)
proceeds to execute the EMAILnotify constructor body.

...

************************************************* *************
#include <iostream>
#include <string>

using namespace std;

class Notify


This is a bad name for a class. A class doesn't "do" anything,
unless it's a functor class. Which this isn't.

{
public:
Notify(void){ cout << "Constructing Notify: " << this << endl; }


Style.
'void' as an argument list is a C'ism which you'd better forget.
virtual ~Notify(void){ cout << "Destructing Notify: " << this <<
endl; }
virtual void Send() = 0;
};


Style.
At least one empty line between class declarations is a good idea.
class Notification : public Notify
{
public:
Notification(void){}
Notification(string sNotifyType);
virtual ~Notification(void);
void Send(){ pNotify->Send(); }
private:
Notify* pNotify;

};


Style.
The definitions of the Notification member functions should appear
here, before anything more. One "place" per class in the code.

Design.
Having a pNotify member doesn't seem to serve any useful purpose.
Most probably you have tried to implement too much in one class.
class EMAILnotify : public Notify
{
public:
EMAILnotify(void){}
virtual ~EMAILnotify(void){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification::Notification(string sNotifyType)
{
if(sNotifyType == "EMAIL")


Design.
Don't identify types by strings (in general). Use symbolic constants
if you absolutely have to. But even more to the point: don't identify
types by data unless you really Really REALLY have to.

pNotify = new EMAILnotify; // Causes 2nd Constructor call
}
Notification::~Notification(void)
{
if( NULL != pNotify )


Coding.
No need to check for NULL.

delete pNotify;
}

void main()


C++ standard.
'void main' is not allowed. This is not a valid standard C++ program.

{
Notification* pNotification = new Notification("EMAIL");
pNotification->Send();
delete pNotification;


Style.
The above is not exception safe in any sense. Use a std::auto_ptr.

}


Well that was a great help, its cleared up any queries as to why the
c'tor was being called twice!
Jul 22 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Ramprasad A Padmanabhan | last post by:
Hi all, I am a php newbie, ( doing perl all time till now ). I am a bit confused OOP in php. Suppose I create an instance of a class with the new() function the cronstuctor is called .. fine...
8
by: Simon | last post by:
Hi everyone, Quick question: If I don't use base() in a subclass's construcor, will the base classes constructor be called at any point. It's just, I would have thought that the base class...
7
by: Christian Engström | last post by:
When i compile the program listed below with gcc version 3.3.1 (MinGW on Windows XP) I get the following result: Calling 'func(d)': 'base' copy constructor Calling 'func(*d_handle)': 'base'...
4
by: Xavier | last post by:
Hi, I have a question, in a "dreaded diamond" situation, regarding the following code: ---- Begin code #include <iostream> using namespace std;
1
by: John | last post by:
Hi, Maybe someone can help me with the following: "The first task by any derived class constructor is to call it’s direct or indirect base class constructor implicitly or explicitly", reads the...
12
by: st_ev_fe | last post by:
I've noticed that when constructing a subclass, the base class get's it's contructors called. Is there some way to avoid this? The base class has one variable, which gets initialised to 0. ...
1
by: mwebel | last post by:
Hi ikind of remember this being easy but cant find it on google: i have a base class and a derived class. The base class has two constructors normal and int overloaded one. thing is i want the...
12
by: Hemanth | last post by:
Hi, I have a base class with a static constructor and some abstract methods. Derived classes implement these methods. From articles on the web, it appears that there is no guarentee that this...
3
by: =?Utf-8?B?RWR3aW4=?= | last post by:
Hello Everyone. Below is the code that is in question. --- BEGIN CODE WITHIN INHERITED FORM --- protected virtual void OnFormClosing(object sender, FormClosingEventArgs e) { switch...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.