473,325 Members | 2,712 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,325 software developers and data experts.

After calling constructor, the destructor is called immediately - why?

Hello,

I want to use an object (LowCut) within another object (SampleRateConverter)
like it is written as follows:

class SampleRateConverter
{
public:
SampleRateConverter( int iSourceSampleRate, int iTargetSampleRate )
{
LowCut = LowPassFilter(dCutoff, 512, BLACKMAN); // here
debugger calls first constructor and then destructor ~LowPassFilter
}

private:
LowPassFilter LowCut;

void doSomething();
};

I used the debugger and realized:
After calling the constructor for LowPassFilter within SampleRateConverter,
the destructor of LowPassFilter is called automatically.

That means, the Filter becomes destroyed immediately. So, I cannot use it in
the method doSomething. The Filter allocates a buffer in memory for storing
information.

But using LowPassFilter *LowCut; (pointer) (instead of the version written
above) and creating the Filter with new-operator (new LowPassFilter(..)) it
works?
Then I have to delete this Filter manually by calling delete LowCut.

But why I cannot use the first version? Why does the runtime environment
destroys the Filter object immediately after generating it?
Anything wrong due to OOP design issues?

Kind regards, Michael


Jan 5 '06 #1
4 4916

Michael wrote:
Hello,

I want to use an object (LowCut) within another object (SampleRateConverter)
like it is written as follows:

class SampleRateConverter
{
public:
SampleRateConverter( int iSourceSampleRate, int iTargetSampleRate )
{
LowCut = LowPassFilter(dCutoff, 512, BLACKMAN); // here
debugger calls first constructor and then destructor ~LowPassFilter
}

private:
LowPassFilter LowCut;

void doSomething();
};

I used the debugger and realized:
After calling the constructor for LowPassFilter within SampleRateConverter,
the destructor of LowPassFilter is called automatically.

That means, the Filter becomes destroyed immediately. So, I cannot use it in
the method doSomething. The Filter allocates a buffer in memory for storing
information.

But using LowPassFilter *LowCut; (pointer) (instead of the version written
above) and creating the Filter with new-operator (new LowPassFilter(..)) it
works?
Then I have to delete this Filter manually by calling delete LowCut.

But why I cannot use the first version? Why does the runtime environment
destroys the Filter object immediately after generating it?
Anything wrong due to OOP design issues?

Kind regards, Michael


Try using an initialization list instead:

class SampleRateConverter
{
public:
SampleRateConverter( int iSourceSampleRate, int iTargetSampleRate
)
: LowCut( LowPassFilter(dCutoff, 512, BLACKMAN) )
{}
// ...
};

See the FAQ:

http://www.parashift.com/c++-faq-lit....html#faq-10.6

Cheers! --M

Jan 5 '06 #2
On 2006-01-05 14:21:58 -0500, "Michael" <fe**@hrz.tu-chemnitz.de> said:
Hello,

I want to use an object (LowCut) within another object
(SampleRateConverter) like it is written as follows:

class SampleRateConverter
{
public:
SampleRateConverter( int iSourceSampleRate, int iTargetSampleRate )
{
LowCut = LowPassFilter(dCutoff, 512, BLACKMAN); // here
debugger calls first constructor and then destructor
That is because you are creating a temporary object with the
expression (LowPassFilter(dCutoff, 512, BLACKMAN)). This temporary is
then copied via assignment to the instance variable LowCut, and is then
destroyed (hence the call to the destructor).
}

private:
LowPassFilter LowCut;

void doSomething();
};
Try this (this avoids the creation of a temporary object, and
initializes the member variable directly):

class SampleRateConverter
{
public:
SampleRateConverter( int iSourceSampleRate, int iTargetSampleRate )
: LowCut(dCutoff, 512, BLACKMAN)
{}

private:
LowPassFilter LowCut;

void doSomething();
};

I used the debugger and realized:
After calling the constructor for LowPassFilter within
SampleRateConverter, the destructor of LowPassFilter is called
automatically.

That means, the Filter becomes destroyed immediately. So, I cannot use
it in the method doSomething. The Filter allocates a buffer in memory
for storing information.


this suggests to me that you haven't properly implemented an assignment
operator (or, odds are, copy constructor) for the class LowPassFilter.

--
Clark S. Cox, III
cl*******@gmail.com

Jan 5 '06 #3
You are creating a temporary LowPassFilter object who's scope is only the
assignment operation. If LowPassFilter has a proper copy constructor than
your code should work but isn't optimal because you are creating two LowPassFilters
instead of one. In fact, you are creating three because one more is created
upon initialization of the object (by LowPassFilter's default constructor).
mlimber's advice to use the initialization list saves you the default instance
but still creates a temporary and copies it to your member variable. The
correct way to do this is like so:

class SampleRateConverter
{
private:
LowPassFilter LowCut;

public:
SampleRateConverter( int iSourceSampleRate, int iTargetSampleRate ) :
LowCut(dCutoff, 512, BLACKMAN)
{
// ...
}

void doSomething() { /* work with LowCut */ }
};

Ales

Hello,

I want to use an object (LowCut) within another object
(SampleRateConverter) like it is written as follows:

class SampleRateConverter
{
public:
SampleRateConverter( int iSourceSampleRate, int
iTargetSampleRate )
{
LowCut = LowPassFilter(dCutoff, 512, BLACKMAN); // here
debugger calls first constructor and then destructor ~LowPassFilter
}
private:
LowPassFilter LowCut;
void doSomething();
};
I used the debugger and realized:
After calling the constructor for LowPassFilter within
SampleRateConverter,
the destructor of LowPassFilter is called automatically.
That means, the Filter becomes destroyed immediately. So, I cannot use
it in the method doSomething. The Filter allocates a buffer in memory
for storing information.

But using LowPassFilter *LowCut; (pointer) (instead of the version
written
above) and creating the Filter with new-operator (new
LowPassFilter(..)) it
works?
Then I have to delete this Filter manually by calling delete LowCut.
But why I cannot use the first version? Why does the runtime
environment
destroys the Filter object immediately after generating it?
Anything wrong due to OOP design issues?
Kind regards, Michael

Jan 5 '06 #4
"Michael" <fe**@hrz.tu-chemnitz.de> wrote in
news:dp**********@anderson.hrz.tu-chemnitz.de:
Hello,

I want to use an object (LowCut) within another object
(SampleRateConverter) like it is written as follows:

class SampleRateConverter
{
public:
SampleRateConverter( int iSourceSampleRate, int
iTargetSampleRate ) {
LowCut = LowPassFilter(dCutoff, 512, BLACKMAN); // here
debugger calls first constructor and then destructor ~LowPassFilter
}

private:
LowPassFilter LowCut;

void doSomething();
};

I used the debugger and realized:
After calling the constructor for LowPassFilter within
SampleRateConverter, the destructor of LowPassFilter is called
automatically.
From a pessimistic compiler, you may have 2 constructors, an assignment,
and a destructor called:

- LowCut is default constructed (at the time that SampleRateConverter
is...)
- A temporary LowPassFilter is constructed for the purposes of the
assignment
- As assignment between the temporary and LowCut is performed
- The temporary LowPassFilter is destroyed.
That means, the Filter becomes destroyed immediately. So, I cannot use
it in the method doSomething. The Filter allocates a buffer in memory
for storing information.
_A_ Filter (I presume you really mean LowPassFilter) is destroyed.
There's two of them in there.... since Filter is allocating a buffer, you
may not have correctly implemented your assignment operator.
But using LowPassFilter *LowCut; (pointer) (instead of the version
written above) and creating the Filter with new-operator (new
LowPassFilter(..)) it works?
Then I have to delete this Filter manually by calling delete LowCut.
Sure, it would work. But as you point out, you'll have to manage the
lifetime of the pointer.
But why I cannot use the first version? Why does the runtime
environment destroys the Filter object immediately after generating
it? Anything wrong due to OOP design issues?


Likely because you've violated the "Rule of three": "If a class needs a
destructor, or a copy constructor, or an assignment operator, it needs
them all." What's probably happening is that during the assignment, it's
only copying the pointer that you allocated to in the LowPassFilter.
When the temporary goes out of scope, it probably deletes the memory that
it holds. As a result, you still have a dangling pointer stored inside
of LowCut. When you try to do something with it later on, you get
Undefined Behaviour (it may crash, it may not... luck of the draw...)
Jan 5 '06 #5

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

Similar topics

7
by: Robin Forster | last post by:
I have two classes: aule_gl_window (parent class) and aule_button (sub class) I want to call the super class (parent) constructor code from the sub class constructor.
6
by: giles | last post by:
Hi, Does a compiler generated constructor initialise the data members? Giles
23
by: Fabian Müller | last post by:
Hi all, my question is as follows: If have a class X and a class Y derived from X. Constructor of X is X(param1, param2) . Constructor of Y is Y(param1, ..., param4) .
3
by: rahul8143 | last post by:
hello, I write a following program and have problem in understanding constructors and destructors. #include <iostream.h> class vector { public: double x; double y;
6
by: Fred Zwarts | last post by:
Hello, I am trying to debug some complex debug code. In order to track the use of dynamically allocated memory, I replaced the standard global new and delete operators. (Not for changing the...
11
by: Lloyd Dupont | last post by:
(not I use 2.0, so new return a "normal" pointer and gcnew return a managed one, my question below regarding new concern plain standart C++ allocator) - if I use the default new operator, are all...
8
by: Kannan | last post by:
Some amount of memory is allocated inside the Base Constructor using new. During the construction of a derived object an exception occurred in the constructor of the derived class. Will the...
1
by: newbie | last post by:
This is a snippet from C++ FAQs, which I have never done--- when I do such a thing, I would declare function used by constructor ( in this example, init() ) as static. But I do understand that it...
4
by: raj s | last post by:
Will the below code cause memory leak in c++ class base{ int a; int *pint; someclass objsomeclass; someclass* psomeclass; base(){ objsomeclass = someclass(); psomeclass = new someclass();
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...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work

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.