No Leaf

J

jrwats

So a common pattern in C++ to stop classes from inheriting from a
class is:

class NoInheritBase
{
private:
friend class NoClassesCanInheritFromMe;
NoInheritBase(){ }
};

class NoClassesCanInheritFromMe: virtual NoInherit
{
};

class SomeClass : public NoClassesCanInheritFromMe // Ok, but you
can't call SomeClass' constructor
{
};

int main()
{
//class SomeClass; Compiler error!
}

Does anyone know of a generic (possibly templated) way to make
NoInheritBase such that it does not need to know about
NoClassesCanInheritFromMe?
 
P

Pascal J. Bourguignon

jrwats said:
So a common pattern in C++ to stop classes from inheriting from a
class is:

class NoInheritBase
{
private:
friend class NoClassesCanInheritFromMe;
NoInheritBase(){ }
};

class NoClassesCanInheritFromMe: virtual NoInherit
{
};

class SomeClass : public NoClassesCanInheritFromMe // Ok, but you
can't call SomeClass' constructor
{
};

int main()
{
//class SomeClass; Compiler error!
}

Does anyone know of a generic (possibly templated) way to make
NoInheritBase such that it does not need to know about
NoClassesCanInheritFromMe?

I'm sorry, but I cannot predict the future. I never know that a given
class will never have to be subclassed. You should realize that the
universe still has 15 billion years of usable time, (and even up to
200 billion years with some restrictions). A lot of thing may happen
during that time, that would make you want to subclass those
classes...
 
I

Ivan

So a common pattern in C++ to stop classes from inheriting from a
class is:

class NoInheritBase
{
private:
friend class NoClassesCanInheritFromMe;
NoInheritBase(){ }

};

class NoClassesCanInheritFromMe: virtual NoInherit
{

};

class SomeClass : public NoClassesCanInheritFromMe // Ok, but you
can't call SomeClass' constructor
{

};

int main()
{
//class SomeClass; Compiler error!

}

Does anyone know of a generic (possibly templated) way to make
NoInheritBase such that it does not need to know about
NoClassesCanInheritFromMe?

Your guest & idea is good. I don't know how to deal with this
currently, I will keep think this issue and figure whether this
implementation can be achieved.
 
I

Ivan

So a common pattern in C++ to stop classes from inheriting from a
class is:

class NoInheritBase
{
private:
friend class NoClassesCanInheritFromMe;
NoInheritBase(){ }

};

class NoClassesCanInheritFromMe: virtual NoInherit
{

};

class SomeClass : public NoClassesCanInheritFromMe // Ok, but you
can't call SomeClass' constructor
{

};

int main()
{
//class SomeClass; Compiler error!

}

Does anyone know of a generic (possibly templated) way to make
NoInheritBase such that it does not need to know about
NoClassesCanInheritFromMe?

Your guess & idea is good. I don't know how to deal with this
currently, I will keep think this issue and figure out whether this
implementation can be achieved.
 
I

Ivan

So a common pattern in C++ to stop classes from inheriting from a
class is:

class NoInheritBase
{
private:
friend class NoClassesCanInheritFromMe;
NoInheritBase(){ }

};

class NoClassesCanInheritFromMe: virtual NoInherit
{

};

class SomeClass : public NoClassesCanInheritFromMe // Ok, but you
can't call SomeClass' constructor
{

};

int main()
{
//class SomeClass; Compiler error!

}

Does anyone know of a generic (possibly templated) way to make
NoInheritBase such that it does not need to know about
NoClassesCanInheritFromMe?

Some languages such as Java and C#, they have an keyword "final" to
specify that a class can be derived by other class. Can we use some
techniques to make a class can't be derived by other classes. The
inherit chain sound like below:

+---------+
| class1 |
+---------+
^
|
+---------+
| class2 |
+---------+


class2 inherits from class1, but to use some special techniques to
ensure that any other classes can't inherit from class2. Can this
character be implemented? just like the "final" semantic in java or C#.
 
J

James Kanze

So a common pattern in C++ to stop classes from inheriting
from a class is:

I don't think it's a common pattern. At least, I've never seen
it. There are many reasons for inheriting from a class, not
just the typical OO ones. And blocking them generally isn't a
good idea. (The most obvious reason is in template
metaprogramming: if you can inherit from it, it is a class
type.)
 
K

Kai-Uwe Bux

James said:
I don't think it's a common pattern. At least, I've never seen
it. There are many reasons for inheriting from a class, not
just the typical OO ones. And blocking them generally isn't a
good idea.

I only toyed with the idea of blocking once: whenever the standard marks a
type as implementation defined (e.g., vector::iterator) but does not
guarantee that you can derive from it (note that vector::iterator could be
a pointer) then my library should at least offer a version that flags
attempts do derive as errors. To that end, I would make vector::iterator
final.

(The most obvious reason is in template
metaprogramming: if you can inherit from it, it is a class
type.)

I picked up the following test:

template < typename T >
class is_class_type {

template < typename S >
static yes_type check ( int S::* );

template < typename S >
static no_type check ( ... );

public:

static bool const value =
( sizeof( check<T>( 0 ) ) == sizeof(yes_type) );

}; // is_class_type

As far as I can see, it does not use derivation. What did you have in mind?


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

jrwats said:
So a common pattern in C++ to stop classes from inheriting from a
class is:

class NoInheritBase
{
private:
friend class NoClassesCanInheritFromMe;
NoInheritBase(){ }
};

class NoClassesCanInheritFromMe: virtual NoInherit
{
};

class SomeClass : public NoClassesCanInheritFromMe // Ok, but you
can't call SomeClass' constructor
{
};

int main()
{
//class SomeClass; Compiler error!
}

Does anyone know of a generic (possibly templated) way to make
NoInheritBase such that it does not need to know about
NoClassesCanInheritFromMe?

I take it, the friend declaration is bothering you. Take a look at:

http://groups.google.com/group/comp...7136?lnk=gst&q=sealed&rnum=3#f63980680a2f7136

In post 4 by Gennaro Prota you will find a discussion of:

class final
{
protected:
final();
};

#define FINAL_CLASS private virtual final

// usage:
class my_class : FINAL_CLASS
{};


BTW: as others have pointed out, making a class final is usually a design
flaw in C++. I have the above in my library and so far have never found any
serious use for it.


Best

Kai-Uwe Bux
 
J

James Kanze

I only toyed with the idea of blocking once: whenever the
standard marks a type as implementation defined (e.g.,
vector::iterator) but does not guarantee that you can derive
from it (note that vector::iterator could be a pointer) then
my library should at least offer a version that flags attempts
do derive as errors. To that end, I would make
vector::iterator final.

That's an interesting idea---if the contract doesn't guarantee
derivability, forbid it. On the other hand, it clashes with
code which wants to do something different with class types,
e.g. use a memcpy on non-class types.
I picked up the following test:
template < typename T >
class is_class_type {
template < typename S >
static yes_type check ( int S::* );
template < typename S >
static no_type check ( ... );

static bool const value =
( sizeof( check<T>( 0 ) ) == sizeof(yes_type) );
}; // is_class_type
As far as I can see, it does not use derivation. What did you
have in mind?

I don't really know, to tell the truth. I'm not at all an
expert on template meta-programming---it's far too complicated
for me---, but when the question of adding final classes to C++
was raised, the experts in meta-programming (David Abrahams, for
example) strongly opposed the idea because it would break some
meta-programming idioms. My suggestion in parentheses was just
a quick guess as to why it might be used. (Although come to
think of it... what little meta-programming I've done has used
something along the lines of what you posted.)
 
K

Kai-Uwe Bux

James said:
That's an interesting idea---if the contract doesn't guarantee
derivability, forbid it. On the other hand, it clashes with
code which wants to do something different with class types,
e.g. use a memcpy on non-class types.

The actual clash that I ran into at one point was the other way around a
final allocator. It turned out that the standard library that shipped with
g++ derived from the allocator type in order to make use of empty base
class optimization (saving 4 bytes on container objects). At that point, I
wondered whether the standard should have a "Derivable" concept just as it
has the CopyConstructible and Assignable concepts. It is actually a little
cumbersome to whip up code that achieves the effect of empty base class
optimization _and_ works nicely with final classes. So, allocators would be
a good candidate for requiring them to be derivable.


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,901
Members
47,439
Latest member
elif2sghost

Latest Threads

Top