Archived

This topic is now archived and is closed to further replies.

Coding the Uncreatable

This topic is 5841 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

in "java" make the class "abstract".
in "c++" just have one method that is abstract:

i.e.

class CNonCreatable {
public:
virtual SomeMethod(void) = 0;
};

// the "= 0;" makes the method abstract and thus cannot create an instance of this class. not sure if you need the virtual.

To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.

Share this post


Link to post
Share on other sites
Try this:
  
class CNonCreatable {
public:
virtual ~CNonCreatable(void) = 0;
};

CNonCreatable::~CNonCreatable(void) { }

class CPartition : public CNonCreatable {
public:
int a;
};

I''ve never done this before, but as far as I know it should work .

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
Oluseyi: that''s right, i just couldn''t remember the name even though i use it for my base class "Object" for everything else i do.

To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi
It works. Those "=0" functions are called pure virtual methods (in C++), and you are not permitted to create instances of pure virtual classes (classes with one or more pure virtual methods).


..., and you have to define in your derived class the method defined as pure virtual (int doIt()=0; ) in your super class.


Edited by - Floppy on December 12, 2001 8:08:23 PM

Share this post


Link to post
Share on other sites
quote:
Original post by xyzzy00
Alternatively, you can just make your constructor protected.


That''s quite close to the Singleton pattern, where the private/protected constructor is complemented by a Create() method. If your Create() method indiscriminately returns valid objects, then making the constructor protected is a waste.

However, while a protected constructor will not allow objects of that class to be created, it doesn''t ensure that an instance never exists. That''s specifically what pure virtual functions are for; why not use them?

*shrugs*

No big deal I guess - another preference.

[ GDNet Start Here | GDNet FAQ | MS RTFM | STL | Google ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
And you don''t even have to make every derived class implement the dummy function.

this is valid:

class CNonCreate
{
protected:
virtual void dummyfunc() = 0;
};

void CNonCreate::dummyfunc()
{}

class CCreate : public CNonCreate
{
using CNonCreate::dummyfunc;
public:
};

this way you don''t have to implement the dummyfunc in the derived classes

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
In Delphi you would just say:

  type TAbstractClass = class
public
function AbstractFunc(aParam: Integer): Integer; virtual; abstract;
end;


Not that this would be much help if you are using C++, but it just goes to show that

Delphi Rules!!

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi

That's quite close to the Singleton pattern, where the private/protected constructor is complemented by a Create() method. If your Create() method indiscriminately returns valid objects, then making the constructor protected is a waste.



Why bother with a create member function?

#include <stdexcept>

class myclass
{
public:
myclass() { if( error_condition ) throw std::exception(); }
};



quote:
Original post by DigitalDelusion

...this way you don't have to implement the dummyfunc in the derived classes



This is merely a convoluted way of expressing something that can be more clearly expressed using a protected constructor. That's why we have protected constructors.

BTW, I thought that a pure virtual function is a pure virtual function, even if it has an implementation. IIRC, the language standard says that should a pure virtual function call occur, the program terminates on an error. (I forget exactly which handler it uses.) Can anybody verify this?


gimp: If you can make use of the pure virtual functions to specify the interface of the derived classes, then obviously pure virtual functions are the way to go. Otherwise, use the protected constructor.

- null_pointer

Edited by - null_pointer on December 13, 2001 9:16:10 AM

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
In Delphi you would just say:
(snip)
Not that this would be much help if you are using C++, but it just goes to show that

Delphi Rules!!


The worst part is that the people above you already explained how to do it in c++. You should always read the posts in a topic before posting - you can save yourself a lot of embarassment.

Share this post


Link to post
Share on other sites
quote:
Original post by null_pointer
BTW, I thought that a pure virtual function is a pure virtual function, even if it has an implementation. IIRC, the language standard says that should a pure virtual function call occur, the program terminates on an error. (I forget exactly which handler it uses.) Can anybody verify this?


You are partially correct. Even if you define a function body for a pure-virtual function in the base class, derived classes must override it or they will also be abstract. Not implementing the override and trying to create an object of the derived class will not compile, so it is in fact a compile-time error, not a run-time error. And we all like compile-time errors better than run-time errors.

So what's the point of defining a pure virtual function? It allows derived classes to call the base-class implementation explicitly in their override (or wherever they need to). Personally, I think this is obfuscating and would not espouse the practice, but it is legal.


Edited by - Stoffel on December 13, 2001 5:37:06 PM

Share this post


Link to post
Share on other sites
Thanks all.

As it was my intention initially just to protect a certain class from being created I can solve this problem by just leaving a virtual function pure.

More generically I was curious to see if there was a generic solution that could be wrapped up. I sort of got the idea from the Boost library which has a ''CNonCopyable'' type class you can derive from. My idea was to have a similar clas that prevented direct use of a class. The problem I had was that if I created a generic pure virtual function that I''d have to implement it in the derived class.(As someone else eluded to above).

Protected constructors sounds interesting. Does that place any requirements on a derived class however? For example would a derived class need to reimplement a public constructor, or would the built in one be sufficient?

Many thanks to all the replies



Chris Brodie
http:\\fourth.flipcode.com

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Yes, using the ''protected constructor'' method.. the base class had a protected constructor (and no alternate method of creation).. and the derived classes would need to implement a public constructor (which chains down to the protected base constructor). For example:
class CBase 
{
protected:
CBase() {...}
};

class CDerived : public CBase
{
public:
CDerived() : CBase() {...}
};

xyzzy

Share this post


Link to post
Share on other sites
If you have no other virtual funtions in the base class the protected constructor would be preferable; adding virtual functions adds 4 bytes to the object size...

  
class CHackMister
{
public:
CHackMister(DWORD dwMagicNumber=0)
{
//Do not instance this class!

_ASSERT(dwMagicNumber==0x1234abcd);
}

};

Have the dervied classes explicitly call the base constructor with the magic number

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
Actually, isn''t convention to prefix such a base class with a leading underscore to indicate that it''s a ''private'' implementation class (keep your stinking hands off)?

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
If so then it is a bad convention. Names with leading underscores are reserved for use by the C++ implementation and should not be used by other programmers, because of the possibility of conflict. Use a trailing underscore, or simply drop the convention altogether.

- null_pointer


Edited by - null_pointer on December 15, 2001 12:27:10 PM

Share this post


Link to post
Share on other sites