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;
} 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.
}
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; }
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 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
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 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! This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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
|
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.
|
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)':
|
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;
|
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
| |
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?
|
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);
|
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 ?...
|
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(); }
|
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...
|
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,...
| |
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...
|
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...
|
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,...
|
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...
|
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();...
|
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...
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |