473,320 Members | 1,969 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,320 software developers and data experts.

Is this an OO concept?

I use a template class called Derived to instantiate derived classes of
class Abstract. Is this an OO concept? Here is some code to illustrate:

#include <iostream>

class Abstract
{
public:
virtual void func() const = 0;

virtual ~Abstract() { }
};

template <typename T>
class Derived : public Abstract
{
T obj;
public:
Derived() { }

void func() const { obj.func(); }
};

class A
{
public:
void func() const
{ std::cout << "A::func called" << std::endl; }
};

class B
{
public:
void func() const
{ std::cout << "B::func called" << std::endl; }
};

int main()
{
Abstract *obj = new Derived<A>;
obj->func();

obj = new Derived<B>;
obj->func();
}

The output of the program is:

A::func called
B::func called

Thanks.
Jul 23 '05 #1
14 1361
On Sun, 19 Jun 2005 09:39:07 +0400, Jason Heyes
<ja********@optusnet.com.au> wrote:
I use a template class called Derived to instantiate derived classes of
class Abstract. Is this an OO concept?
Why do you care?
Here is some code to illustrate:

#include <iostream>

class Abstract
{
public:
virtual void func() const = 0;

virtual ~Abstract() { }
};

template <typename T>
class Derived : public Abstract
{
T obj;
public:
Derived() { }

void func() const { obj.func(); }
};


Derived template is the adapter design pattern. It uses object composition
to add Abstract interface to the contained object. And it's perfectly OO.

--
Maxim Yegorushkin
Jul 23 '05 #2
"Maxim Yegorushkin" <e-*****@yandex.ru> wrote in message
news:op.sslslhogti5cme@home...
On Sun, 19 Jun 2005 09:39:07 +0400, Jason Heyes
<ja********@optusnet.com.au> wrote:
I use a template class called Derived to instantiate derived classes of
class Abstract. Is this an OO concept?
Why do you care?


I would like to find the right naming for my classes.
Here is some code to illustrate:

#include <iostream>

class Abstract
{
public:
virtual void func() const = 0;

virtual ~Abstract() { }
};

template <typename T>
class Derived : public Abstract
{
T obj;
public:
Derived() { }

void func() const { obj.func(); }
};


Derived template is the adapter design pattern. It uses object composition
to add Abstract interface to the contained object. And it's perfectly OO.


Ok. I'd better rename Derived to Adapter. Thanks for the information.
Jul 23 '05 #3
Jason Heyes wrote:
I use a template class called Derived to instantiate derived classes of
class Abstract. Is this an OO concept?


i hope u do realize the fact that only Derived (or now Adapter) is the
_only_ derived class of Abstract. classes A & B r diff classes. ur
template class imposes the restriction on objects that they must have
func() defined. i wouldnt exactly attribute such template restrictions
to OO. instead u might wanna try:

class Abstract {
public:
virtual void func() const = 0;
};

class Caller {
Abstract *x;
public:
Caller() { x = NULL; }
Caller(Abstract *x) { this->x = x; }
~Caller() { if(x) delete x; }
void func() { if(x) x->func(); }
void set_x(Abstract *x)
{ if(this->x) delete this->x;
this->x = x; }
// u might wanna try overloadin da = operator
// but keep in mind that <Caller obj> = new <Abstract derived> won't
work!
};

class A : public Abstract {
public:
void func() const { cout << "A" << endl; }
};

class B : public Abstract {
public:
void func() const { cout << "B" << endl; }
};

int main()
{
Caller c(new A);
c.func();
c.set_x(new B);
c.func();
return 0;
}

Jul 23 '05 #4
He is probably not allowed to modify A and B. If he could, then I don't
see why you would need a Caller class at all.
class Caller {
Abstract *x;
public:
Caller() { x = NULL; }
Caller(Abstract *x) { this->x = x; }
~Caller() { if(x) delete x; }
void func() { if(x) x->func(); }
void set_x(Abstract *x)
{ if(this->x) delete this->x;
this->x = x; }
// u might wanna try overloadin da = operator
// but keep in mind that <Caller obj> = new <Abstract derived> won't
work!
};
Well, i hope you realize you are passing a pointer to an object you have
not created and then you are deleting it in the destructor. That's not
good "OO" either. You need to keep in mind implementation details, too
bad. There are some typical solutions for such problems, like reference
counter, master pointers, or the simple thing of making responsible for
the deletion of the object to its creator.
forayer wrote: Jason Heyes wrote:
I use a template class called Derived to instantiate derived classes of
class Abstract. Is this an OO concept?

i hope u do realize the fact that only Derived (or now Adapter) is the
_only_ derived class of Abstract. classes A & B r diff classes. ur
template class imposes the restriction on objects that they must have
func() defined. i wouldnt exactly attribute such template restrictions
to OO. instead u might wanna try:

class Abstract {
public:
virtual void func() const = 0;
};

class Caller {
Abstract *x;
public:
Caller() { x = NULL; }
Caller(Abstract *x) { this->x = x; }
~Caller() { if(x) delete x; }
void func() { if(x) x->func(); }
void set_x(Abstract *x)
{ if(this->x) delete this->x;
this->x = x; }
// u might wanna try overloadin da = operator
// but keep in mind that <Caller obj> = new <Abstract derived> won't
work!
};

class A : public Abstract {
public:
void func() const { cout << "A" << endl; }
};

class B : public Abstract {
public:
void func() const { cout << "B" << endl; }
};

int main()
{
Caller c(new A);
c.func();
c.set_x(new B);
c.func();
return 0;
}

Jul 23 '05 #5

"forayer" <th********@hotmail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Jason Heyes wrote:
> I use a template class called Derived to instantiate derived classes of> class Abstract. Is this an OO concept?

i hope u do realize the fact that only Derived (or now Adapter) is the
_only_ derived class of Abstract. classes A & B r diff classes. ur
template class imposes the restriction on objects that they must have
func() defined. i wouldnt exactly attribute such template restrictions
to OO. instead u might wanna try:


Bad design. And thanks for the memory leak. The Abstract class requires a
virtual destructor since you are deleting derived objects through an
Abstract pointer. Look up initialization lists as well.

#include <iostream>
#include <stdexcept>

class Abstract {
virtual ~Abstract() { std::cout << "~Abstract"\n; }
public:
virtual void func() const = 0;
};

class Caller {
Abstract *x;
public:
Caller() { x = NULL; }
Caller() : x(0) { }
Caller(Abstract *x) { this->x = x; }
Caller(Abstract *p) : x(p) { }
~Caller() { if(x) delete x; }
void func() { if(x) x->func(); }
void func() throw(std::exception)
{
try
{
if (x == 0)
throw std::exception("Error: func() called on a null object\n");
x->func();
}
catch( const std::exception& e)
{
std::cout << e.what();
}
}
void set_x(Abstract *x)
{ if(this->x) delete this->x;
this->x = x; }
where is the copy constructor? If you choose to disable it:

private:
Abstract(const Abstract& r_copy_);
// u might wanna try overloadin da = operator
// but keep in mind that <Caller obj> = new <Abstract derived> won't
work!
};

class A : public Abstract {
public:
void func() const { cout << "A" << endl; }
};

class B : public Abstract {
public:
void func() const { cout << "B" << endl; }
};

int main()
{
Caller c(new A);
c.func();
c.set_x(new B);
c.func();
return 0;
}


with an Abstract non-virtual d~tor (or the compiler generated equivalent):

A
~Abstract
B
~Abstract

.... memory leak ... ~A and ~B are never invoked

with Abstract virtual d~tor:

A
~A
~Abstract
B
~B
~Abstract

.... ok ...

Jul 23 '05 #6
david wrote:
He is probably not allowed to modify A and B. If he could, then I don't
see why you would need a Caller class at all.
You're right, if that's the case then it doesnt.
Well, i hope you realize you are passing a pointer to an object you have
not created and then you are deleting it in the destructor.


Where am I doing that??? As far as I can see, I am just passing a base
class pointer, which could very well be pointing to a derived class
object. besides, i do check if it is a null pointer before deleting the
object pointed to.
Could you clarify your statement, please?

forayer

Jul 23 '05 #7

Sorry, i understand my english is bad, i'll make an effort:
Caller(Abstract *x) { this->x = x; }
void set_x(Abstract *x) these are two ways of initializing a Caller object. You are passing as
parameters an Abstract object that someone else created. ~Caller() { if(x) delete x; }

In the above destructor you are deleting the object pointed by x, but of
course you don't know wether it's a shared object, and you are deleting
it, so you are imposing through your particular implementation that just
the object Caller may use the object pointed by x and no one else. This,
for example, wouldn't be valid:

void do_bad_things (Abstract * a) {
Caller caller ( a );
caller.func ();
.... // more things
} <<<< After returning, the object pointed by "a" has been deleted.

This would be better:
~Caller() { }
Jul 23 '05 #8
david wrote:
> Caller(Abstract *x) { this->x = x; }
> void set_x(Abstract *x)

these are two ways of initializing a Caller object. You are passing as
parameters an Abstract object that someone else created.


Well, I am passing only a pointer to the object. Besides, whatever
object the passed pointer points to has to be a derived class object of
class Abstract (since class Abstract is, well, abstract!). I figured
that since:
Abstract *x = new A;
x->func();
x = new B;
x->func();
is valid, I could use the same technique in class Caller. Of course,
this makes sense only if class Caller is made use of as a class
factory.

> ~Caller() { if(x) delete x; }

In the above destructor you are deleting the object pointed by x, but of
course you don't know wether it's a shared object, and you are deleting
it, so you are imposing through your particular implementation that just
the object Caller may use the object pointed by x and no one else.


I agree. But if you take a look at the main() function in the first
post by Jason Heyes, you will see that the Derived<A> object is left
dangling when Derived<B> is created and assigned. So I thought a little
cleanup action might tidy up such things.

rgds,
forayer

Jul 23 '05 #9

"forayer" <th********@hotmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
david wrote:

I agree. But if you take a look at the main() function in the first
post by Jason Heyes, you will see that the Derived<A> object is left
dangling when Derived<B> is created and assigned. So I thought a little
cleanup action might tidy up such things.


And you dangled both since:

~Caller() { if(x) delete x; }

only deletes the Abstract portion of the derived class (x is a base pointer
and Abstract doesn't have a virtual d~tor).

Jul 23 '05 #10
Peter Julian wrote:
"forayer" <th********@hotmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
david wrote:

I agree. But if you take a look at the main() function in the first
post by Jason Heyes, you will see that the Derived<A> object is left
dangling when Derived<B> is created and assigned. So I thought a little
cleanup action might tidy up such things.


And you dangled both since:

~Caller() { if(x) delete x; }

only deletes the Abstract portion of the derived class (x is a base pointer
and Abstract doesn't have a virtual d~tor).


Yes I did, and you did make it quite clear in your last message, thank
you.

cheers,
forayer

Jul 23 '05 #11
"forayer" <th********@hotmail.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Peter Julian wrote:
"forayer" <th********@hotmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
> david wrote:
>
> I agree. But if you take a look at the main() function in the first
> post by Jason Heyes, you will see that the Derived<A> object is left
> dangling when Derived<B> is created and assigned. So I thought a little
> cleanup action might tidy up such things.
>


And you dangled both since:

~Caller() { if(x) delete x; }

only deletes the Abstract portion of the derived class (x is a base
pointer
and Abstract doesn't have a virtual d~tor).


Yes I did, and you did make it quite clear in your last message, thank
you.


Don't worry about it forayer. I did the same in my original post. :P
Jul 23 '05 #12

"forayer" <th********@hotmail.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Peter Julian wrote:
"forayer" <th********@hotmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
david wrote:

<snip>

Yes I did, and you did make it quite clear in your last message, thank
you.


What Jason said: don't worry about it.

Since it doesn't make sense to virtualize all d~tors that come along, i'ld
suggest defining any ctor, copy_ctor and d~tor for non-PODs and non-trivial
classes. Placing an assertion / ouput displaying the ctor/dtor invocation
will prevent the leak from biting you.

Jul 23 '05 #13

And you dangled both since:

~Caller() { if(x) delete x; }

only deletes the Abstract portion of the derived class (x is a base pointer
and Abstract doesn't have a virtual d~tor).


Sorry, maybe I'm mistaken here, but doesn't the standard say that
the memory will be released correctly no matter if I delete via
a base-class pointer or via the pointer to the complete object?
Of course if I delete via a base-class pointer and that base-class
does not define a virtual dtor, then the derived dtor will not be
called. But I think if the derived class has nothing to clean up
it would be perfectly fine with the standard. Ugly as hell of
course, but that's another story.
After all the signature of the "global operator delete" is
"void(void*)".
And of course if any/some of the involved classes have it's own
"operator delete" defined things could be different. But then again,
that's even another story.

And please stop the "if(p) delete p;" thing. "delete p;" is
just fine.
Jul 23 '05 #14

"Swampmonster" <sw**********@der-ball-ist-rund.net> wrote in message
news:11***************@news.liwest.at...

And you dangled both since:

~Caller() { if(x) delete x; }

only deletes the Abstract portion of the derived class (x is a base pointer and Abstract doesn't have a virtual d~tor).

Sorry, maybe I'm mistaken here, but doesn't the standard say that
the memory will be released correctly no matter if I delete via
a base-class pointer or via the pointer to the complete object?


No. There is no stack available to destroy the object's remnants at
end_of_lifetime. If you new a derived instance via a base pointer without a
virtual d~tor, and then delete with that pointer: the result is undefined
behaviour.
Of course if I delete via a base-class pointer and that base-class
does not define a virtual dtor, then the derived dtor will not be
called. But I think if the derived class has nothing to clean up
it would be perfectly fine with the standard. Ugly as hell of
course, but that's another story.
Basicly, the compiler relenquishes *all* deallocation of that instance once
you've taken over that responsability. Even if you do find a particular
compiler or implementation that does zap the derivative through a
non-virtual base d~tor, its still UB.

The instance of the derived class has at a minimum a pointer to its base
(whether or not that base pointer is actually valid is irrelevent). The fact
remains that its part of the allocation when derived was newed.
After all the signature of the "global operator delete" is
"void(void*)".
And of course if any/some of the involved classes have it's own
"operator delete" defined things could be different. But then again,
that's even another story.


Jul 23 '05 #15

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

Similar topics

10
by: nop90 | last post by:
Proof of concept: Currently I have a web hosting service and it does support php. Can the following be done in php? Explanations or examples would be appreciated. Create 2 applications, app-1...
1
by: Dick | last post by:
Before going in to details i like to understand more about concept and design of this database. Most books go directly in to details. Please, can a current admistrator gife me information on...
4
by: jabailo | last post by:
These guys have it going on. They actually use design ideas that Microsoft employees can drool upon. Visual Studio 2010 Concept IDE http://www.codeproject.com/csharp/Concept_IDE.asp "Like...
3
by: Ramza Brown | last post by:
I have this concept I throwing together. It is not professional or anything, just something I thought might be interesting. The concept is business(me) - to - consumer. It is, What did you buy?....
0
by: duelearning | last post by:
I do not think that on the current market, or being developed, there is a real concept search tool. The key issue is that nobody has offered a satisfactory answer on what a concept is and its...
7
by: srinivas | last post by:
Hi, I am a asp programmer.I am displaying the db records in the html pages in a web page.I have 500 columns and 1000 rows in that html table.Here i am planning to implement the "MS-Excel Freeze...
4
by: mohan | last post by:
Hi All, How to implement virtual concept ( dynamic polymorphism ) in c. I guess i should create a void pointer which is pointing to the function. Not clear about this Does anyone have some idea...
1
by: nimrod | last post by:
i have this problem to solve but not sure how to go about it.can anyone help me please. Environment = market Concept one to many each have action buy and action sell When multiple concepts...
0
by: ParasakthiGuru | last post by:
hai, i don't know Replication concept if anybody can know that replication concept pls sent to me replication brief tutorials By Guru
2
Subsciber123
by: Subsciber123 | last post by:
I am writing a program to create family trees. It is stable, but I would say that it is still in the pre-alpha stage. Anyway, I would like to be able to export the tree to a concept map. Does...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
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)...
0
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: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

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.