Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > classes in a class

Reply
Thread Tools

classes in a class

 
 
Joe C
Guest
Posts: n/a
 
      09-16-2004
I have a class that performs transformations on data streams. As written,
the class constructor takes several parameters and a data-source to produce
it's stream.

I have the need to combine the output of two instances of this class to
generate a third data stream. (think eg of applying a filters to audio)

When I do this, the parameters that I supply the second class are dependent
upon the state of the system after the first transform has occured.

I have been accomplishing this by using a function outside the class that
instantiates the two classes as the information needed to instantiate them
becomes available. Once both objects are built, their output is combined
and the function exits, the objects are destroyed, and the caller gets his
transformed data.

I don't like this solution because my objects cease to exist once I return
the data...but I want to keem them around for a while longer.

So...as a solution, I decided to create a new class that would hold the two
instances of my transforming class objects and return the combined data. My
problem is...how can I construct my two member-data objects when the
construction parameters of the second object depend upon having made some
calculations on the first, successfully constructed object?

I can't supply the constructor parameters for the second object in the
initialization list because those parameters require some processing *after*
the first object is constructed.

Thanks for your thoughts

Joe



 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      09-16-2004
Joe C wrote:
> I have a class that performs transformations on data streams. As written,
> the class constructor takes several parameters and a data-source to produce
> it's stream.
>
> I have the need to combine the output of two instances of this class to
> generate a third data stream. (think eg of applying a filters to audio)
>
> When I do this, the parameters that I supply the second class are dependent
> upon the state of the system after the first transform has occured.
>
> I have been accomplishing this by using a function outside the class that
> instantiates the two classes as the information needed to instantiate them
> becomes available. Once both objects are built, their output is combined
> and the function exits, the objects are destroyed, and the caller gets his
> transformed data.
>
> I don't like this solution because my objects cease to exist once I return
> the data...but I want to keem them around for a while longer.
>
> So...as a solution, I decided to create a new class that would hold the two
> instances of my transforming class objects and return the combined data. My
> problem is...how can I construct my two member-data objects when the
> construction parameters of the second object depend upon having made some
> calculations on the first, successfully constructed object?
>
> I can't supply the constructor parameters for the second object in the
> initialization list because those parameters require some processing *after*
> the first object is constructed.


Make the second subobject a dynamic one and construct it using 'new':

class myclass {
myfirstauxiliaryclass aux1;
mysecondauxiliaryclass *paux2;
public:
myclass() : aux1(parameters) {
somecalculations(aux1);
paux2 = new mysecondauxiliaryclass(otherparameters);
}
};

Victor
 
Reply With Quote
 
 
 
 
Joe C
Guest
Posts: n/a
 
      09-16-2004

"Victor Bazarov" <(E-Mail Removed)> wrote in message > Make the
second subobject a dynamic one and construct it using 'new':
>
> class myclass {
> myfirstauxiliaryclass aux1;
> mysecondauxiliaryclass *paux2;
> public:
> myclass() : aux1(parameters) {
> somecalculations(aux1);
> paux2 = new mysecondauxiliaryclass(otherparameters);
> }
> };
>
> Victor


Thanks Victor. This is exactly what I need. I guess it should have been
obvious to me but...well...it wasn't 8-\ Thanks again for 'getting' my
question, and giving me a straight forward solution.


 
Reply With Quote
 
Cy Edmunds
Guest
Posts: n/a
 
      09-17-2004
"Joe C" <(E-Mail Removed)> wrote in message
news:w0l2d.145768$(E-Mail Removed) t...
>
> "Victor Bazarov" <(E-Mail Removed)> wrote in message > Make the
> second subobject a dynamic one and construct it using 'new':
> >
> > class myclass {
> > myfirstauxiliaryclass aux1;
> > mysecondauxiliaryclass *paux2;
> > public:
> > myclass() : aux1(parameters) {
> > somecalculations(aux1);
> > paux2 = new mysecondauxiliaryclass(otherparameters);
> > }
> > };
> >
> > Victor

>
> Thanks Victor. This is exactly what I need. I guess it should have been
> obvious to me but...well...it wasn't 8-\ Thanks again for 'getting' my
> question, and giving me a straight forward solution.
>
>


It isn't quite as straight forward as you might think. The code as written
has a memory leak -- operator delete is never called. Of course you can add
a destructor with a delete statement, but then you really should add a copy
constructor and an assignment operator, remembering of course to avoid the
x=x bug in an exception-safe matter. No big deal, but still...

You could use a smart pointer, but it can also be done without any pointers
at all:

class two_things
{
private:
thing a;
thing b;
public:
two_things(arg_type arg) : a(arg), b(a) {}
// other stuff
};

This may look dangerous, but the standard guarantees that member variables
are intialized in the order they are declared. Thus a is constructed before
b and is safe to use as an argument for b's constructor.

--
Cy
http://home.rochester.rr.com/cyhome/


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      09-17-2004
"Cy Edmunds" <(E-Mail Removed)> wrote...
> "Joe C" <(E-Mail Removed)> wrote in message
> news:w0l2d.145768$(E-Mail Removed) t...
>>
>> "Victor Bazarov" <(E-Mail Removed)> wrote in message > Make the
>> second subobject a dynamic one and construct it using 'new':
>> >
>> > class myclass {
>> > myfirstauxiliaryclass aux1;
>> > mysecondauxiliaryclass *paux2;
>> > public:
>> > myclass() : aux1(parameters) {
>> > somecalculations(aux1);
>> > paux2 = new mysecondauxiliaryclass(otherparameters);
>> > }
>> > };
>> >
>> > Victor

>>
>> Thanks Victor. This is exactly what I need. I guess it should have been
>> obvious to me but...well...it wasn't 8-\ Thanks again for 'getting' my
>> question, and giving me a straight forward solution.
>>
>>

>
> It isn't quite as straight forward as you might think. The code as written
> has a memory leak -- operator delete is never called. Of course you can
> add
> a destructor with a delete statement, but then you really should add a
> copy
> constructor and an assignment operator, remembering of course to avoid the
> x=x bug in an exception-safe matter. No big deal, but still...
>
> You could use a smart pointer, but it can also be done without any
> pointers
> at all:
>
> class two_things
> {
> private:
> thing a;
> thing b;
> public:
> two_things(arg_type arg) : a(arg), b(a) {}
> // other stuff
> };
>
> This may look dangerous, but the standard guarantees that member variables
> are intialized in the order they are declared. Thus a is constructed
> before
> b and is safe to use as an argument for b's constructor.


Yes, and to perform that extra calculation you could declare a dummy member
and initialise it with the value returned by that calculation function:

class two_things
{
thing_one a;
int dummy;
thing_two b;

int some_extra_calculations(thing_one&);

public:
two_things(some_arguments)
: a(whatever)
, dummy(some_extra_calculations(a)
, b(something_else)
{
}
};

Given certain assumptions, everything is possible.

V


 
Reply With Quote
 
Joe C
Guest
Posts: n/a
 
      09-17-2004

"Cy Edmunds" <(E-Mail Removed)> wrote in message
news:n3t2d.232865$(E-Mail Removed). ..
> "Joe C" <(E-Mail Removed)> wrote in message
> news:w0l2d.145768$(E-Mail Removed) t...
>>
>> "Victor Bazarov" <(E-Mail Removed)> wrote in message > Make the
>> second subobject a dynamic one and construct it using 'new':
>> >
>> > class myclass {
>> > myfirstauxiliaryclass aux1;
>> > mysecondauxiliaryclass *paux2;
>> > public:
>> > myclass() : aux1(parameters) {
>> > somecalculations(aux1);
>> > paux2 = new mysecondauxiliaryclass(otherparameters);
>> > }
>> > };
>> >
>> > Victor

>>
>> Thanks Victor. This is exactly what I need. I guess it should have been
>> obvious to me but...well...it wasn't 8-\ Thanks again for 'getting' my
>> question, and giving me a straight forward solution.
>>
>>

>
> It isn't quite as straight forward as you might think. The code as written
> has a memory leak -- operator delete is never called. Of course you can
> add
> a destructor with a delete statement, but then you really should add a
> copy
> constructor and an assignment operator, remembering of course to avoid the
> x=x bug in an exception-safe matter. No big deal, but still...


Thanks for the comments. I used Vics method, and...as I guess Victor
guessed, we were on the same page regarding cleaning up memory.

>
> You could use a smart pointer, but it can also be done without any
> pointers
> at all:
>
> class two_things
> {
> private:
> thing a;
> thing b;
> public:
> two_things(arg_type arg) : a(arg), b(a) {}
> // other stuff
> };
>
> This may look dangerous, but the standard guarantees that member variables
> are intialized in the order they are declared. Thus a is constructed
> before
> b and is safe to use as an argument for b's constructor.
>

I don't think this technique will work, unless I modify the 'thing' class to
do the calculations that b needed...which doesn't make logical sense for
this class. I can't use your method because the method of generating the
parameters needed to instantiate b from a requires about 10 lines of code.
Anyway, thanks for offering another approach.


 
Reply With Quote
 
Joe C
Guest
Posts: n/a
 
      09-17-2004

"Victor Bazarov" <(E-Mail Removed)> wrote in message
news:t8t2d.103477$3l3.48115@attbi_s03...
> "Cy Edmunds" <(E-Mail Removed)> wrote...
>> "Joe C" <(E-Mail Removed)> wrote in message
>> news:w0l2d.145768$(E-Mail Removed) t...
>>>
>>> "Victor Bazarov" <(E-Mail Removed)> wrote in message > Make the
>>> second subobject a dynamic one and construct it using 'new':
>>> >
>>> > class myclass {
>>> > myfirstauxiliaryclass aux1;
>>> > mysecondauxiliaryclass *paux2;
>>> > public:
>>> > myclass() : aux1(parameters) {
>>> > somecalculations(aux1);
>>> > paux2 = new mysecondauxiliaryclass(otherparameters);
>>> > }
>>> > };
>>> >
>>> > Victor
>>>
>>> Thanks Victor. This is exactly what I need. I guess it should have
>>> been
>>> obvious to me but...well...it wasn't 8-\ Thanks again for 'getting' my
>>> question, and giving me a straight forward solution.
>>>
>>>

>>
>> It isn't quite as straight forward as you might think. The code as
>> written
>> has a memory leak -- operator delete is never called. Of course you can
>> add
>> a destructor with a delete statement, but then you really should add a
>> copy
>> constructor and an assignment operator, remembering of course to avoid
>> the
>> x=x bug in an exception-safe matter. No big deal, but still...
>>
>> You could use a smart pointer, but it can also be done without any
>> pointers
>> at all:
>>
>> class two_things
>> {
>> private:
>> thing a;
>> thing b;
>> public:
>> two_things(arg_type arg) : a(arg), b(a) {}
>> // other stuff
>> };
>>
>> This may look dangerous, but the standard guarantees that member
>> variables
>> are intialized in the order they are declared. Thus a is constructed
>> before
>> b and is safe to use as an argument for b's constructor.

>
> Yes, and to perform that extra calculation you could declare a dummy
> member
> and initialise it with the value returned by that calculation function:
>
> class two_things
> {
> thing_one a;
> int dummy;
> thing_two b;
>
> int some_extra_calculations(thing_one&);
>
> public:
> two_things(some_arguments)
> : a(whatever)
> , dummy(some_extra_calculations(a)
> , b(something_else)
> {
> }
> };
>
> Given certain assumptions, everything is possible.
>
> V


The class actually instantiates with a struct and a container ...the dummy
method would have gotten a little ugly. For this particular problem, I
think the pointer method you first offered was the more natural approach
compared to forcing it to happen in the initialization list. The only
downside is that one "thing" gets.treatment() while the other "thing"
gets->treatment() which is slightly awkward to have two very similar things
requiring different syntax. However, as this is hidden in the two_things
class, it doesn't really matter much.

Thanks guys.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Class A contains class B, class B points to class A Joseph Turian C++ 5 12-30-2005 03:24 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
Classes within classes David ASP .Net 2 07-22-2005 07:13 PM
A parameterized class (i.e. template class / class template) is not a class? christopher diggins C++ 16 05-04-2005 12:26 AM
How to access inner classes variables & methods from outer classes lonelyplanet999 Java 1 11-13-2003 01:54 PM



Advertisments