By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,407 Members | 1,033 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,407 IT Pros & Developers. It's quick & easy.

MC++ problem with virtual function overrides and collection editor

P: n/a
In C++ an overridden virtual function in a derived class must have the exact
same signature of the function which is overridden in the base class, except
for the return type which may return a pointer or reference to a derived
type of the base class's return type.

In .NET the overridden virtual function is similar, but an actual parameter
of the function can be a derived reference from the base class's reference
also.

This dichotomy can create a problem when using MC++ to override virtual
properties. In MC++ one can never override a virtual property by using a
derived reference type for the base class's reference type. In .NET one can
specify an overridden property which is a derived reference type from the
base class's reference type.

This dichotomy comes into play when creating a custom collection class in
MC++. The typical custom collection in other .NET languages overrides the
Item type in CollectionBase, not only to provide type-safe usage but to
creating a more specific type than an 'object' reference which the
collection editor in the Component Designer and Windows Form Designer will
understand to allow specific types to be added to a collection.

In MC++, however, it appears that the Item type must still be the 'object'
reference ( Object * in MC++ ) since it is impossible to override the
set_Item function with a different type than an Object * because of
paragraph 1 above. This means that because the get_Item and set_Item must
refer to the same type, the type must be Object * for an MC++ custom
collection class. Of course MC++ can still provide type-safe usage by not
allowing anything but the actual Item object, whatever it is, to be added,
inserted, and removed from the collection. However as far as the collection
editor in the Component Designer and Windows Form Designer is concerned, any
object is a possibility to be added to such a collection.

Is there a way around this difference between MC++ other .NET languages
other than writing one's collections in another .NET language and creating a
separate assembly just for the collection, or accepting the limitation of
MC++ as far as the collection editor is concerned ?
Nov 17 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Edward,

The .NET Framework 1.1 SDK documentation topic for class CollectionBase
includes a C++ sample, and this sample does compile and run correctly on
the .NET Framework 1.1.

This example does not compile with the C++ compiler that comes with the
..NET Framework 1.0 SDK, however. If I understand correctly, two
differences between VC++ 7.0 and VC++ 7.1 are at play here:
- If a __gc class declares a method whose name and parameter list match
an interface method, then VC++ 7.0 assumes that the programmer wants to
implement the interface method and, thus, requires that the return type
is covariant. VC++ 7.1, however, does not assume this. If the return
type is not covariant, VC++ 7.1 considers both methods to be unrelated.
- If a __gc class declares two methods with the same name and parameter
types, then VC++ 7.0 requires that they are both qualified with an
interface name. VC++ 7.1, however, allows one method to be unqualified.

In short, VC++ 7.0 behaves more like C++ and VC++ 7.1 behaves more like C#.

Your analysis contains some errors. See below.

Edward Diener wrote:
In C++ an overridden virtual function in a derived class must have the exact
same signature of the function which is overridden in the base class, except
for the return type which may return a pointer or reference to a derived
type of the base class's return type.
I agree.
In .NET the overridden virtual function is similar, but an actual parameter
of the function can be a derived reference from the base class's reference
also.
I believe that, for all intents and purposes, this statement is false,
and that in .NET, a method m1 overrides a method m2 only if the
parameter types list and the return type of m1 are equal to those of m2.
In this case, .NET is more strict than C++, and not the other way
around. My belief is supported by all known current implementations, as
well as by the C# Language Specification, which says, in section 10.5.4:
"An override method overrides an inherited virtual method with the same
signature." The same section also says that it is an error if the
override declaration and the overridden base method do not have the same
return type. Interestingly, I was not able to find language in the
Common Language Infrastructure (CLI) specification that supports either
of our views. The CLI says that the callvirt instruction calls the
method that "matches" the name and signature specified in the
instruction. Note that in CLI terminology, the signature includes the
return type. The problem is that "to match" could be interpreted as "to
equal", but it could also be interpreted as allowing covariance.

This is very interesting food for language lawyers, but a more relevant
point is that creating a strongly typed collection class using
CollectionBase does not require covariance.

For example: Please see the Int16Collection example in the 1.1
documentation for CollectionBase. The set_Item(int,Int16) method does
not override the set_Item(int,object) method. These two methods are
unrelated. The Int16Collection class serves its purpose as a strongly
typed collection class, even in the absence of covariance.
This dichotomy can create a problem when using MC++ to override virtual
properties. In MC++ one can never override a virtual property by using a
derived reference type for the base class's reference type. In .NET one can
specify an overridden property which is a derived reference type from the
base class's reference type.
Sentence 2 is true; sentence 3 is false.
This dichotomy comes into play when creating a custom collection class in
MC++. The typical custom collection in other .NET languages overrides the
Item type in CollectionBase, not only to provide type-safe usage but to
creating a more specific type than an 'object' reference which the
collection editor in the Component Designer and Windows Form Designer will
understand to allow specific types to be added to a collection.
Custom collection classes declare an Item property, and this property is
retrieved through reflection by the Designers, but this property does
not override the Item property declared by IList.
In MC++, however, it appears that the Item type must still be the 'object'
reference ( Object * in MC++ ) since it is impossible to override the
set_Item function with a different type than an Object * because of
paragraph 1 above. This means that because the get_Item and set_Item must
refer to the same type, the type must be Object * for an MC++ custom
collection class.
The point is that VC++ 7.0 does not allow a function declaration whose
name and parameter types list are equal to a function in a base type,
except if the declared function overrides the function in the base type.
VC++ 7.1 does allow this (for __gc classes at least).
Is there a way around this difference between MC++ other .NET languages
other than writing one's collections in another .NET language and creating a
separate assembly just for the collection, or accepting the limitation of
MC++ as far as the collection editor is concerned ?


I do not think it is possible in VC++ 7.0.

Greetings

Bart Jacobs

Nov 17 '05 #2

P: n/a
Bart Jacobs wrote:
Edward,

The .NET Framework 1.1 SDK documentation topic for class
CollectionBase includes a C++ sample, and this sample does compile
and run correctly on the .NET Framework 1.1.

This example does not compile with the C++ compiler that comes with
the .NET Framework 1.0 SDK, however. If I understand correctly, two
differences between VC++ 7.0 and VC++ 7.1 are at play here:
- If a __gc class declares a method whose name and parameter list
match
an interface method, then VC++ 7.0 assumes that the programmer wants
to implement the interface method and, thus, requires that the return
type
is covariant. VC++ 7.1, however, does not assume this. If the return
type is not covariant, VC++ 7.1 considers both methods to be
unrelated. - If a __gc class declares two methods with the same name
and parameter types, then VC++ 7.0 requires that they are both
qualified with an interface name. VC++ 7.1, however, allows one
method to be unqualified.

In short, VC++ 7.0 behaves more like C++ and VC++ 7.1 behaves more
like C#.
Thanks for this elucidation.

Your analysis contains some errors. See below.

Edward Diener wrote:
In C++ an overridden virtual function in a derived class must have
the exact same signature of the function which is overridden in the
base class, except for the return type which may return a pointer or
reference to a derived type of the base class's return type.
I agree.
In .NET the overridden virtual function is similar, but an actual
parameter of the function can be a derived reference from the base
class's reference also.


I believe that, for all intents and purposes, this statement is false,


You are correct and it is my error in thinking so.
snipped...
This dichotomy comes into play when creating a custom collection
class in MC++. The typical custom collection in other .NET languages
overrides the Item type in CollectionBase, not only to provide
type-safe usage but to creating a more specific type than an
'object' reference which the collection editor in the Component
Designer and Windows Form Designer will understand to allow specific
types to be added to a collection.
Custom collection classes declare an Item property, and this property
is retrieved through reflection by the Designers, but this property
does
not override the Item property declared by IList.


This is what led to my wrong thinking and misunderstanding of virtual
function overrides in .NET. I had assumed that the implementations of custom
collection classes were overriding virtual functions in the base
CollectionBase class, without closing looking at the code in the examples or
even noticing that there was a version for MC++ using Int16. They are
actually overloading functionality, using covariant parameter and return
types, and not overriding them. I hadn't made the association that
reflection was at work in the Collection Editor of the Windows Form Designer
and Component Designer rather than normal polymorphism, but there was no
documentation that this was happening. So I naively assumed that .NET
allowed co-variant parameters as well as covariant return types in its
overrides, which was the only way I could think of that custom collection
classes would work at design time. Evidently the Collection Editor assumes
common property and member function names for a custom collection class but
adjusts to the covariant parameters and/or return types for those names
through reflection. In that case, creating a type-safe class in MC++ works
fine, at least with the VC++ 7.1 compiler, without having to resort to
'object' being the common type in all properties and member functions.
In MC++, however, it appears that the Item type must still be the
'object' reference ( Object * in MC++ ) since it is impossible to
override the set_Item function with a different type than an Object
* because of paragraph 1 above. This means that because the get_Item
and set_Item must refer to the same type, the type must be Object *
for an MC++ custom collection class.
The point is that VC++ 7.0 does not allow a function declaration whose
name and parameter types list are equal to a function in a base type,
except if the declared function overrides the function in the base
type. VC++ 7.1 does allow this (for __gc classes at least).


Yes that would force one in .NET 2002 to override, rather than overload,
CollectionBase properties and methods. But I think that there are notes in
the CollectionBase doc pointing out that certain functionality is not
supported in the 1.0 framework.
Is there a way around this difference between MC++ other .NET
languages other than writing one's collections in another .NET
language and creating a separate assembly just for the collection,
or accepting the limitation of MC++ as far as the collection editor
is concerned ?


I do not think it is possible in VC++ 7.0.


Thanks for all the information and for correcting my false impression of how
the Collection Editor worked with custom collection types.
Nov 17 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.