473,657 Members | 2,395 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 << "Constructi ng Notify: " << this << endl; }
virtual ~Notify(void){ cout << "Destructin g Notify: " << this <<
endl; }
virtual void Send() = 0;
};
class Notification : public Notify
{
public:
Notification(vo id){}
Notification(st ring sNotifyType);
virtual ~Notification(v oid);
void Send(){ pNotify->Send(); }
private:
Notify* pNotify;

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

void main()
{
Notification* pNotification = new Notification("E MAIL");
pNotification->Send();
delete pNotification;
}
Jul 22 '05 #1
6 3685
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 << "Constructi ng Notify: " << this << endl; }
Style.
'void' as an argument list is a C'ism which you'd better forget.
virtual ~Notify(void){ cout << "Destructin g 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(vo id){}
Notification(st ring sNotifyType);
virtual ~Notification(v oid);
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(voi d){}
virtual ~EMAILnotify(vo id){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification:: Notification(st ring 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(v oid)
{
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("E MAIL");
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 << "Constructi ng Notify: " << this << endl; }
virtual ~Notify(void){ cout << "Destructin g Notify: " << this <<
endl; }
virtual void Send() = 0;
};
class Notification : public Notify
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^ inherit 1
{
public:
Notification(vo id){}
Notification(st ring sNotifyType);
virtual ~Notification(v oid);
void Send(){ pNotify->Send(); }
private:
Notify* pNotify;

};
class EMAILnotify : public Notify

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

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

virtual ~EMAILnotify(vo id){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification::N otification(str ing sNotifyType) : Notify() // implicit construct of Notify

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

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

int main()
{
Notification* pNotification = new Notification("E MAIL");
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("E MAIL");

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 << "Constructi ng 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 << "Destructin g 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(vo id){}
Notification(st ring sNotifyType);
virtual ~Notification(v oid);
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(voi d){}
virtual ~EMAILnotify(vo id){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification:: Notification(st ring 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(v oid)
{
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("E MAIL");
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 EmailNotificati on( "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 << "Constructi ng Notify: " << this << endl; }


Style.
'void' as an argument list is a C'ism which you'd better forget.
virtual ~Notify(void){ cout << "Destructin g 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(vo id){}
Notification(st ring sNotifyType);
virtual ~Notification(v oid);
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(voi d){}
virtual ~EMAILnotify(vo id){};
virtual void Send(){ cout << "Send() Email: " << this << endl; }
};
Notification:: Notification(st ring 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(v oid)
{
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("E MAIL");
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
2274
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 Now if the class *extends* another class the constructor of base class is not called. But is there a way I can tell php to execute all
8
1413
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 constructor would always need to be called before anything else seeing as the subclass may well depend on functionality and variables created in the base class.
7
1620
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' copy constructor Calling 'func(d_handle)':
4
4611
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
2249
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 statement. To test this, I added messageboxes in all constructors indicating which constructor is called. There are four constructors which could be called: 1. Base class empty constructor 2. Base class 2-Par. constructor
12
5797
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. The subclass's constructor sets this variable to a real value. So first the variable is set to 0, the variable is never used before it once again gets set to a real value. It's a waste. Any ideas anyone?
1
1876
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 derived class to call the constructors for the base class using also the same kind of overloading. like this: class BASE{ public: BASE(); BASE(int x);
12
3429
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 static constructor of the base class would be invoked even if a an object of the derived class is created. Is this correct ? Is there any way to ensure the base class's static constructor is invoked before the derived class instance is constructed ?...
3
2163
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 (e.CloseReason) { case CloseReason.UserClosing: if (this.AskUserIfOkayToClose() == true) { this.ExecuteApplicationCloseProcedures(); }
0
8394
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8306
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8825
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8732
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8503
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7327
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5632
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4152
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
1955
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.