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

"Virtual constructor" abstract base class - feasibility?

Hi,

I have the following header file in my 'everything useful I think of
in one place' library:

============= BEGIN CODE SNIPPET ===========

/** All classes that derive from this obtain a 'virtual constructor' -
ie if the 'clone()' method is called on a polymorphic type, an
object of the same (unknown) type is returned. */
class CloneService
{
public:
virtual ~CloneService()
{
}

/// This MUST be overridden in children classes. Abstract
/// classes might want to override this too (and keep it
/// abstract), as it will make it more convenient for users to
/// use pointers of those classes.
virtual CloneService*
clone() const = 0;
};

/// Makes it easy to check at compile time if a given template
/// parameter class has the 'clone' method.
template<typename T>
bool
check_clone_service_requirements()
{
T* (T::*test)() const = &T::clone;
test = test;

return true;
}

============= END CODE SNIPPET ===========

Could someone tell me the feasibility of having something like this?
I've used it in a few places and found it useful, but I always do
something like:

class Base : public CloneService
{
// ...
Base* clone() const = 0;
// ...
};

class Child : public CloneService
{
// ...
Child* clone() const {return new Child(*this);}
// ...
};

i.e. I have to redeclare the clone virtual method in the abstract
virtual base class definition anyway. Can anyone thing of any
situations where having a 'CloneService' base class for all cloneable
classes everywhere would be useful?

And I realise now that the name 'Cloneable' is a better one than
'CloneService' - but that's what using too much Java does to you.

Thanks,
Asfand Yar

--
Entry in RollerCoaster Tycoon 2 readme.txt file:
RollerCoaster Tycoon2 must be played on a video card capable of
640x480 screen resolution at a bit depth setting of 256 bits.
And the proof that playing too many strategy games causes loss of
humour: http://tinyurl.com/dyrtt
Jan 19 '06 #1
8 4010
On Thu, 19 Jan 2006 11:37:00 +0000, Asfand Yar Qazi
<ay****@qazi.f2s.com> wrote:
Hi,

I have the following header file in my 'everything useful I think of
in one place' library:

============= BEGIN CODE SNIPPET ===========

/** All classes that derive from this obtain a 'virtual constructor' -
ie if the 'clone()' method is called on a polymorphic type, an
object of the same (unknown) type is returned. */
class CloneService
{
public:
virtual ~CloneService()
{
}

/// This MUST be overridden in children classes. Abstract
/// classes might want to override this too (and keep it
/// abstract), as it will make it more convenient for users to
/// use pointers of those classes.
virtual CloneService*
clone() const = 0;
};

/// Makes it easy to check at compile time if a given template
/// parameter class has the 'clone' method.
template<typename T>
bool
check_clone_service_requirements()
{
T* (T::*test)() const = &T::clone;
test = test;

return true;
}

============= END CODE SNIPPET ===========

Could someone tell me the feasibility of having something like this?
I've used it in a few places and found it useful, but I always do
something like:

class Base : public CloneService
{
// ...
Base* clone() const = 0;
// ...
};

class Child : public CloneService
{
// ...
Child* clone() const {return new Child(*this);}
// ...
};

i.e. I have to redeclare the clone virtual method in the abstract
virtual base class definition anyway. Can anyone thing of any
situations where having a 'CloneService' base class for all cloneable
classes everywhere would be useful?

And I realise now that the name 'Cloneable' is a better one than
'CloneService' - but that's what using too much Java does to you.


The problem I see is the fact that clients can now create containers
of pointers to CloneService, although these might be otherwise totally
incompatible types with no other methods in common. IOW, you have the
same design problem as if every single type in your project might
derive from a class called "CObject" (ever heard of MFC?)

--
Bob Hairgrove
No**********@Home.com
Jan 19 '06 #2
Asfand Yar Qazi wrote:
Hi,

I have the following header file in my 'everything useful I think of
in one place' library:

============= BEGIN CODE SNIPPET ===========

/** All classes that derive from this obtain a 'virtual constructor' -
ie if the 'clone()' method is called on a polymorphic type, an
object of the same (unknown) type is returned. */
class CloneService
{
public:
virtual ~CloneService()
{
}

/// This MUST be overridden in children classes. Abstract
/// classes might want to override this too (and keep it
/// abstract), as it will make it more convenient for users to
/// use pointers of those classes.
virtual CloneService*
clone() const = 0;
};

/// Makes it easy to check at compile time if a given template
/// parameter class has the 'clone' method.
template<typename T>
bool
check_clone_service_requirements()
{
T* (T::*test)() const = &T::clone;
test = test;

return true;
}


It only makes it easier, if you have the derive type to check it with.
If your pointer does not match the derive type, then the above code
will fail to catch the error at compile time.
It's still better then nothing, but it's not fail proof.
I use a similar method in the following policy class smart pointer:
http://code.axter.com/smart_ptr.h

If you look at the clone_static_function_allocator_policy, you'll see
that it uses a static clone function, instead of the normal virtual
clone function.

If a derived type is used that doesn't have the static function
declared, it will cause a compile time error.
But this method also is not fail proof, since a derived pointer could
be used to a derived-derived type, and than it will fail to produce an
error if the derived-derived type has no clone function.

Jan 19 '06 #3
Bob Hairgrove wrote:
<snip>

The problem I see is the fact that clients can now create containers
of pointers to CloneService, although these might be otherwise totally
incompatible types with no other methods in common. IOW, you have the
same design problem as if every single type in your project might
derive from a class called "CObject" (ever heard of MFC?)


Ah - I see. From now on, I will simply declare the virtual clone() function in
every base class I produce, and they will be totally unrelated in terms of
ancestry. Thanks for the advice

--
Entry in RollerCoaster Tycoon 2 readme.txt file:
RollerCoaster Tycoon2 must be played on a video card capable of 640x480 screen
resolution at a bit depth setting of 256 bits.
And the proof that playing too many strategy games causes loss of humour:
http://tinyurl.com/dyrtt
Jan 22 '06 #4
Asfand Yar Qazi wrote:
Bob Hairgrove wrote:
<snip>

The problem I see is the fact that clients can now create containers
of pointers to CloneService, although these might be otherwise totally
incompatible types with no other methods in common. IOW, you have the
same design problem as if every single type in your project might
derive from a class called "CObject" (ever heard of MFC?)


Ah - I see. From now on, I will simply declare the virtual clone() function in
every base class I produce, and they will be totally unrelated in terms of
ancestry. Thanks for the advice


I think clone() has more to do with prototype design pattern than with
virtual constructor (factory design pattern). Ask in comp.object too.

Jan 22 '06 #5
Asfand Yar Qazi wrote:
i.e. I have to redeclare the clone virtual method in the abstract
virtual base class definition anyway. Can anyone thing of any
situations where having a 'CloneService' base class for all cloneable
classes everywhere would be useful?


I don't think it's useful, for the same reason that there isn't a
common std::object base class, or even a common base class for all STL
iterators. You're free to define clone() methods wherever you need
them. Having a common parent which requires this (and doesn't solve
the problem of multi-level inheritance) only allows you to treat all
such objects polymorphically. Is there some OO justification for
treating completely unrelated classes polymorphically? Not in any
defensible design, I think.

But yeah, tell that to Java.

Look into compile-time polymorphism with templates. It accomplishes
what you're trying to do, without necessitating meaningless
inheritance. Once you grasp the point that inheritance is far from the
only kind of relationship between types, you'll be a much happier
coder.

Oh, and read some books from the "C++ In-Depth" series, particularly
Alexandrescu and Sutter.

Luke

Jan 22 '06 #6
Luke Meyers wrote:

Look into compile-time polymorphism with templates. It accomplishes
what you're trying to do, without necessitating meaningless
inheritance. Once you grasp the point that inheritance is far from the
only kind of relationship between types, you'll be a much happier
coder.
Sometimes I need to clone something that I know the base type of, but do not
know what the object actually is. That's what I need a virtual constructor (or
whatever the design pattern people call it).

Oh, and read some books from the "C++ In-Depth" series, particularly
Alexandrescu and Sutter.


Will do.

--
Entry in RollerCoaster Tycoon 2 readme.txt file:
RollerCoaster Tycoon2 must be played on a video card capable of 640x480 screen
resolution at a bit depth setting of 256 bits.
And the proof that playing too many strategy games causes loss of humour:
http://tinyurl.com/dyrtt
Jan 25 '06 #8
Asfand Yar Qazi wrote:
Luke Meyers wrote:

Look into compile-time polymorphism with templates. It accomplishes
what you're trying to do, without necessitating meaningless
inheritance. Once you grasp the point that inheritance is far from the
only kind of relationship between types, you'll be a much happier
coder.


Sometimes I need to clone something that I know the base type of, but do not
know what the object actually is. That's what I need a virtual constructor (or
whatever the design pattern people call it).


Right, and that's fine. Because you know the base type, you can see
the base type's virtual clone() member function and use it. That
provides exactly what you'd want. Introducing a separate Cloneable
parent just complicates the situation and gains you nothing.

Luke

Jan 25 '06 #9

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

Similar topics

12
by: cppaddict | last post by:
Hi, I know that it is illegal in C++ to have a static pure virtual method, but it seems something like this would be useful when the following 2 conditions hold: 1. You know that every one...
14
by: mshetty | last post by:
Hi, I get an error "Warning: b::a_method hides the virtual function a::a_method()." on compiling the following code.. #include <iostream.h> class a {
5
by: Duck Dodgers | last post by:
Here is my situation class base { }; class child1 { int data; }; class child2 {
175
by: Ken Brady | last post by:
I'm on a team building some class libraries to be used by many other projects. Some members of our team insist that "All public methods should be virtual" just in case "anything needs to be...
4
by: Jon Shemitz | last post by:
Syntax seems to say "modifiers is modifiers" and either is valid, but Google searches seem to show that "public virtual" is more common. Is there any sort of (semi) official convention? -- ...
19
by: Martin Oddman | last post by:
Hi, I have a compiling problem. Please take a look at the code below. I have an application that is built upon three tiers: one data tier (Foo.DataManager), one business tier (Foo.Kernel) and...
4
by: mwebel | last post by:
Hi, i have a StuffProducer(SProd) and a StuffContainer(SCont) basis class. -SProd produces values, that are stored in SCont. -Derived classes of both are compatible only on the same derivated...
7
by: desktop | last post by:
This page: http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html start with the line: "Virtual functions allow polymorphism on a single argument". What does that exactly mean? I guess it...
1
by: Bart Simpson | last post by:
Can anyone explain the concept of "slicing" with respect to the "virtual constructor" idiom as explain at parashift ? From parashift: class Shape { public: virtual ~Shape() { } ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
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,...
0
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,...
0
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...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.