May a ref class be stored by value in a managed class? - c++-cli

Say I have a managed type Foo:
ref class Foo
{};
And a managed type Bar:
ref class Bar
{
Foo foo;
};
Note that Bar does not contain a Foo^, but a Foo.
Assume that Bar is gcnew'd.
Is this permitted?
It compiles without warning, yet the documentation says:
Reference (ref) types can only be instantiated on the managed heap, not on the stack or on the native heap. Value types can be instantiated on the stack or the managed heap.
I suppose it's transitively "on the managed heap", but I'd like confirmation.
Reason I ask is that I'm possibly seeing some evidence that my foo is corrupt when I later access it; MCVE perhaps to follow in a subsequent question, depending on the outcome of this one!

It seems to be valid.
The language is specified by ECMA-372, which does not appear to prevent this (though I cannot immediately find any explicitly stated semantics for it, either).
In particular, §23 (p141) lists restrictions on "mixed types":
This clause is reserved for possible future use.
A mixed type is a native class, ref class, or native array that requires object members, either by declaration or by inheritance, to be allocated on both the CLI heap and some other part of memory.
Examples of mixed types are:
A native class containing a member whose type is a non-simple value type, a ref class type, or interface class type.
A native array of elements whose type is a value type other than a fundamental type, or a ref class type.
A ref class or value class containing a member whose type is a native class or native array.
A program that defines or declares a mixed type is ill-formed.
…and your example is not one of them. I'd expect to find it listed there if it were prohibited.
(not sure what's going on with that first paragraph)

Related

What's wrong with hiding virtual method of a base class?

I have been getting Delphi compiler warnings about Method 'Create' hides virtual method of base.
I have reviewed several Stack Overflow links (see below), and I don't understand the logic behind this warning, and why it is considered bad coding practice. I'm hoping others can help me understand
I will include some sample code:
type
TMachine = class(TPersistent)
private
public
Horsepower : integer;
procedure Assign(Source : TMachine);
end;
...
procedure TMachine.Assign(Source : TMachine);
begin
inherited Assign(Source);
Self.Horsepower := Source.HorsePower;
end;
This causes the compiler warning.
[dcc32 Warning] Unit1.pas(21): W1010 Method 'Assign' hides virtual method of base type 'TPersistent'
I have been ignoring this warning because it didn't make any sense to me. But that got me in trouble in another way (see my other post here: Why does Delphi call incorrect constructor during dynamic object creation?) so I have decided to try to understand this better.
I know that if I use the reserved word reintroduce, the error will go away, but I have seen it repeatedly posted that this is a bad idea. As Warren P wrote here (Delphi: Method 'Create' hides virtual method of base - but it's right there), "IMHO, if you need reintroduce, your code smells horrible".
I think I understand what is meant by "hiding". As David Heffernan said here (What causes "W1010 Method '%s' hides virtual method of base type '%s'" warning?):
What is meant by hiding is that from the derived class you no longer have access to the virtual method declared in the base class. You cannot refer to it since it has the same name as the method declared in the derived class. And that latter method is the one that is visible from the derived class.
But I am somewhat confused because it seems that ancestor method is not really hidden, because a derived class can always just use the inherited keyword to call the method in the base class. So 'hidden' really means 'somewhat hidden'?
I think I also understand that using the reserved word override will prevent the compiler warning, but the procedure signature has to be the same (i.e. no newly added parameters). That I can't use that here.
What I don't understand is why hiding is something to be warned about. In my code example above, I would not want users of TMachine.Assign() to instead somehow use TPersistent.Assign(). In my extended class, I have extended needs, and therefore want to them to use the new and improved function. So it seems like hiding the older code is exactly what I want. My understanding of a virtual method is one where the correct method is called based on the actual type of an object at run time. I don't think that should have any bearing in this case.
Additional code, to be added to example code above
TAutomobile = class(TMachine)
public
NumOfDoors : integer;
constructor Create(NumOfDoors, AHorsepower : integer);
end;
...
constructor TAutomobile.Create(ANumOfDoors, AHorsepower : integer);
begin
Inherited Create(AHorsepower);
NumOfDoors := ANumOfDoors;
end;
This adds new compiler warning message: [dcc32 Warning] Unit1.pas(27): W1010 Method 'Create' hides virtual method of base type 'TMachine'
I especially don't understand problems that arise with using new constructors with additional parameters. In this post (SerialForms.pas(17): W1010 Method 'Create' hides virtual method of base type 'TComponent'), the wisdom seems to be that a constructor with a different name should be introduced, e.g. CreateWithSize. This would seem to allow users to pick and choose which constructor they want to use.
And if they choose the the old constructor the extended class might be missing some needed information for creation. But if, instead, I 'hide' the prior constructor, it is somehow bad programming. Marjan Venema wrote about reintroduce in this same link: Reintroduce breaks polymorphism. Which means that you can no longer use meta classes (TxxxClass = class of Tyyy) to instantiate your TComponent descendant as its Create won't be called. I don't understand this at all.
Perhaps I need to understand polymorphism better. Tony Stark wrote in this link (What is polymorphism, what is it for, and how is it used?) that polymorphism is: "the concept of object oriented programming.The ability of different objects to respond, each in its own way, to identical messages is called polymorphism." So am I presenting a different interface, i.e. no longer an identical message, and thus this breaks polymorphism?
What am I missing? In summary, isn't hiding base code a good thing in my examples?
The danger here is that you might call Assign on a base class reference. Because you did not use override then your derived class method is not called. You have thus subverted polymorphism.
By the principle of least surprise you should use override here, or give your derived class method a different name. The latter option is simple. The former looks like this:
type
TMachine = class(TPersistent)
public
Horsepower : integer;
procedure Assign(Source : TPersistent); override;
end;
...
procedure TMachine.Assign(Source : TPersistent);
begin
if Source is TMachine then begin
Horsepower := TMachine(Source).Horsepower;
end else begin
inherited Assign(Source);
end;
end;
This allows your class to co-operate with the polymorphic design of TPersistent. Without using override that would not be possible.
Your next example, with virtual constructors is similar. The entire point of making a constructor virtual is so that you can create instances without knowing their type until runtime. The canonical example is the streaming framework, the framework that processes .dfm/.fmx files and creates objects and sets their properties.
That streaming framework relies on the virtual constructor of TComponent:
constructor Create(AOwner: TComponent); virtual;
If you want a component to work with the streaming framework, you must override this constructor. If you hide it, then the streaming framework cannot find your constructor.
Consider how the streaming framework instantiates components. It does not know about all the component classes it needs to work with. It cannot, for instance consider third party code, the code you write. The Delphi RTL cannot know about types defined there. The streaming framework instantiates components like this:
type
TComponentClass = class of TComponent;
var
ClassName: string;
ClassType: TComponentClass;
NewComponent: TComponent;
....
ClassName := ...; // read class name from .dfm/.fmx file
ClassType := GetClass(ClassName); // a reference to the class to be instantiated
NewComponent := ClassType.Create(...); // instantiate the component
The ClassType variable holds a meta class. This allows us to represent a type which is not known until runtime. We need the call to Create to be dispatched polymorphically so that the code in the component's constructor is executed. Unless you use override when declaring that constructor, it won't be.
Really, all of this boils down to polymorphism. If your understanding of polymorphism is not firm, as you suggest, then you will struggle to appreciate any of this. I think your next move is to get a better grip on what polymorphism is.
There are different benefits for using inheritance. In your examples you do it to avoid coding the same things again and again. So if TMachine has Horsepower field already and some methods and now you need more advanced TAutomobile with NumOfDoors, you make it TMachine descendant.
If you now always treat them differently, i.e in some code you use exactly TMachine (machine := TMachine.Create(...), machine.Assign(AnotherMachine) etc. ) and in another code you use TAutomobile and they never get mixed
then you're all right, you can ignore these warnings or 'mute' them with reintroduce.
But there is usually another aspect of inheritance: keeping uniform interface, or as it's sometimes called: 'contract'. Separating interface from implementation.
For example, form is able to free all the objects which belong to it, no matter what these objects are, that's because of Destroy method which gets overrided. Form doesn't care about your implementation, but it knows: to free the object it just have to call Destroy, that easy. If you don't override Destroy, that's extremely bad: no way TForm will call you as TMachine.Destroy. It'll call you as TObject.Destroy, but it won't lead to your TMachine.Destroy, so you get a memory leak. In most cases when some method wasn't overriden it's just because programmer forgot to do it, thus a warning: it's very helpful one. If programmer didn't forget it but that was intentionally, reintroduce keyword is used. This way programmer tells: "Yes, I know what I do, this is intentionally, don't disturb me!"
TPersistent.Assign is another procedure which is frequently called from base class, not derived (that is: we don't want to pay attention to implementation, we just want to copy an object, whatever it is). For example, TMemo has Lines: TStrings, but TStrings is an abstract class, while the actual implementation is TStringList. So, when you write Memo1.Lines.Assign(Memo2.Lines), the TStrings.Assign method is used. It may implement this assign through another methods: clear itself first and then add line after line. Some TStrings descendant may want to speed-up process by some block copy of data. Of course it has to use exactly Assign(Source: TPersistent) method and override it, otherwise it is never called (inherited is called instead).
Classic implementation of Assign is like this:
procedure TMachine.Assign(Source : TPersistent);
begin
if Source is TMachine then
Horsepower := TMachine(Source).Horsepower
else inherited Assign(Source);
end;
That's the case when inherited shouldn't be called first thing. Here it is 'the last resort': it's called last if nothing else helped. It makes one final try: if your class don't know how to assign, maybe that Source knows how to AssignTo your class?
For example, TBitmap was coded long, long ago. After that TPngImage was developed to work with, well, PNG. You want to put PNG into bitmap and write: Bitmap.Assign(PngImage). No way TBitmap may know how to deal with PNG: it didn't exist back then! But TPngImage writer knew that may happen and implemented AssignTo method which is able to convert it to bitmap. So TBitmap as the last straw calls TPersistent.Assign method and that in turn calls TPngImage.AssignTo and that works like a charm.
Is this side of inheritance needed in your program is up to you. If there is again lots of dublicating code (the one which deals with machines and another with automobiles) or there are lots of conditions, then something is wrong and some good polymorphism might be of help.

Redis Serialization and Deserialization

I have noticed that some of my serialized objects stored in Redis have problems deserializing.
This typically occurs when I make changes to the object class being stored in Redis.
I want to understand the problem so that I can have a clear design for a solution.
My question is, what causes deserialization problems?
Would a removal of a public/private property cause a problem?
Adding new properties, perhaps?
Would a adding a new function to the class create problems? How about more constructors?
In my serialized object, I have a property Map, what if I change (updated some properties, added functions, etc) myObject, would it cause a deserialization problem?
what causes deserialization problems?
I would like to give you bit of background before answering your question,
The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException.
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, It uses the following information of the class to compute SerialVersionUID,
The class name.
The class modifiers written as a 32-bit integer.
The name of each interface sorted by name.
For each field of the class sorted by field name (except private static and private transient fields:
The name of the field.
The modifiers of the field written as a 32-bit integer.
The descriptor of the field.
if a class initializer exists, write out the following:
The name of the method, .
The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
The descriptor of the method, ()V.
For each non-private constructor sorted by method name and signature:
The name of the method, .
The modifiers of the method written as a 32-bit integer.
The descriptor of the method.
For each non-private method sorted by method name and signature:
The name of the method.
The modifiers of the method written as a 32-bit integer.
The descriptor of the method.
So, to answer your question,
Would a removal of a public/private property cause a problem? Adding new properties, perhaps? Would a adding a new function to the class create problems? How about more constructors?
Yes, all these additions/removal by default will cause the problem.
But one way to overcome this is to explicitly define the SerialVersionUID, this will tell the serialization system that i know the class will evolve (or evolved) over the time and don't throw an error. So the de-serialization system reads only those fields that are present in both the side and assigns the value. Newly added fields on the de-serialization side will get the default values. If some fields are deleted on the de-serialization side, the algorithm just reads and skips.
Following is the way one can declare the SerialVersionUID,
private static final long serialVersionUID = 3487495895819393L;

What's the package of a Java array class?

This question is for JVM specification advocates. According to the JVMS, Java SE 7 edition, section 5.3.3, last paragraph:
If the component type is a reference type, the accessibility of the array class is determined by the accessibility of its component type. Otherwise, the accessibility of the array class is public.
Thus an array class can have package visibility. Logically I would expect that, if foo.baz.MyClass has package visibility, then an array of MyClass is visible only to package foo.baz. But I can't find anything in the specification supporting this view. Section 5.3 says that the run-time package, that should be used to determine visibility constraints, is built of the binary name of the package plus the defining classloader. But the binary name comes from the classfile, and array classes do not have classfiles. Similar issue for the primitive classes (e.g., Boolean.TYPE), which apparently have public visibility, but I cannot find information about them anywhere.
Can you spot a point in the JVMS where the package of array/primitive classes is clearly defined (or a reason why there is none)?
Isn't that exactly what the quote from the specification is saying?
If the component type is a reference type, the accessibility of the array class is determined by the accessibility of its component type.
If you have a class some.pkg.SomeClass and want to use it as some.pkg.SomeClass[] the accessibility is determined by the accessibility of its component type. In this case the component type is some.pkg.SomeClass.
The other case is for native types, and you can't add more native types to Java.

specific questions about scope and property reference in actionscript 3

I've been battling with AS3 for a little while now, and I'm working on a simple application using only actionscript and the FlashDevelop/flex-compiler combo. I've hit a bit of a wall in my fledgling OOP understanding, and I'm wondering whether someone might be able to point me in the right direction. I have genuinely read several books, and spent many hours reading online tutorials etc, but something's just not clicking!
What's baffling me is this: When something is declared 'public', according to what I read, it is therefore available anywhere in the application (and should therfore be used with care!) However, when I try to use public properties and methods in my program, they most definitely are not available anywhere other than from the class/object that instantiated them.
This leads me to conclude that even if objects (of different class) are instantiated from the same (say 'main') class, they are not able to communicate with each other at all, even through public members.
If so, then fair enough, but I've honestly not seen this explained properly anywhere. More to the point, how do different objects communicate with other then? and what does Public actually mean then, if it only works through a direct composition hierarchy? If one has to write applications based only on communication from composer class to it's own objects (and presumably use events for, er, everything else?) - isn't this incredibly restrictive?
I'm sure this is basic OOP stuff, so my apologies in advance!
Any quick tips or links would be massively appreciated.
There are different topics you are covering in your question. Let me clarify:
What does the modifier public mean?
How can instances of the same class communicate to each other?
--
1.
In OOP you organize your code with objects. An object needs to be instantiated to provide its functionality. The place where you instantiate the object can be considered as the "context". In Flash the context might be the first frame, in a pure AS3 movie, it might be the main class, in Flex it could be the main mxml file. In fact, the context is always an object, too. Class modifier of your object public class MyClass tells your context whether it is allowed to instantiate the object or not. If set to internal, the context must live in the same directory as the class of the object. Otherwise it is not allowed to create a new object of the class. Private or protected are not valid class modifiers. Public class ... means that any context may create an object of that class. Next: Not only instantiation is controlled by these modifiers but also the visibility of a type. If set to internal, you cannot use an expression like var obj : InternalType in a context that does not live in the same directory as Internal type.
What about methods and properties? Even if your context is allowed to access a type, certain properties and methods might be restricted internal/protected/private var/method and you perhaps are not able to invoke them.
Why we're having such restrictions? Answer is simple: Differnent developers may develop different parts of the same software. These parts should communicate only over defined interfaces. These interfaces should be as small as possible. The developer therefore declares as much code as possible to be hidden from outside and only the necessary types and properties publicly available.
Don't mix up with modifiers and global properties. The modifier only tells you if a context is allowed to see a type or method. The global variable is available throughout the code. So even if a class is declared to be public, instances of that class do not know each other by default. You can let them know by:
storing the instances in global variables
providing setter such as set obj1(obj1 : OBJ1) : void where each object needs to store the reference in an instance variable
passing the object as method arguments: doSomething(obj1 : OBJ1)
Hope this helps you to more understand OOP. I am happy to answer your follow up questions.
Jens
#Jens answer (disclaimer: I skimmed) appears to be completely correct.
However, I'm not sure it answers your question very directly, so I'll add a bit here.
A public property is a property of that class instance that is available for other objects to use(function: call, variable: access, etc). However, to use them you must have a reference (like a very basic pointer, if that helps?) to that object instance. The object that instantiates (creates, new ...) that object can take that reference by assigning it to a variable of that class type.
// Reference is now stored in 's'
public ExampleClass s = new ExampleClass();
If you'd like to, you do have the option of making a static property, which is available just by knowing the class name. That property will be shared by all instances of that class, and any external class can refer to it (assuming it's public static) by referring to the class name.
A public property is referred to by the reference you stored.
//public property access
s.foo
s.bar(var)
A static property is referred to by the class name.
//static property access
ExampleClass.foo
ExampleClass.bar(var)
Once you've created the instance, and stored the reference, to an object, you can pass it around as you'd like. The below object of type OtherExampleClass would receive the reference to 's' in its constructor, and would have to store it in a local variable of its own to keep the reference.
public OtherExampleClass s2 = new OtherExampleClass(s);

What's wrong with Copy Constructors? Why use Cloneable interface?

When programming C++ we used to create copy constructors when needed (or so we were taught). When switching to Java a few years ago, I noticed that the Cloneable interface is now being used instead. C# followed the same route defining the ICloneable interface. It seems to me that cloning is part of the definition of OOP. But I wonder, why were these interfaces created, and the copy constructor seems to have been dropped?
When I thought about it, I came to the thought that a copy constructor would not be useful if one needs to make a copy of an object whose type is not known (as in having a reference to a base type). This seems logical. But I wonder whether there are other reasons that I do not know of, for which the Cloneable interfaces have been favored over copy constructors?
I think it's because there is no such inherent need for a copy constructor in Java and in C# for reference types. In C++ objects are named. You can (and you will most often) copy (and in C++1x move) them around e.g when returning from functions, since returning pointers require you to allocate dynamic memory which would be slow and painful to manage. The syntax is T(x) so it makes sense to make a constructor taking a T reference. C++ couldn't make a clone function, since that would require returning an object by value again (and thus another copy).
But in Java, objects are unnamed. There are only references to them, which can be copied, but the object itself isn't copied. For the cases when you actually need to copy them, you can use the clone call (but i read in other anwers clone is flawed. i'm no java programmer so i cannot comment that). Since not the object itself is returned, but rather a reference to it, a clone function will suffice. Also a clone function can be overriden. That's not going to work with copy constructors. And incidentally, in C++ when you need to copy a polymorphic object, a clone function is required too. It's got a name, the so-called virtual copy constructor.
Because C++ and Java (and C#) aren't the same thing. C++ has no built-in interfaces because interfaces aren't part of the language. You can fake them with abstract classes but they aren't how you think about C++. Also, in C++ assignment is normally deep.
In Java and C# assignment just involves copying the handle to the internal object. Basically when you see:
SomeClass x = new SomeClass();
in Java or C#, there's a level of indirection builtin that doesn't exist in C++. In C++, you write:
SomeClass* x = new SomeClass();
Assignment in C++ involves the dereferenced value:
*x = *another_x;
In Java you can get access to the "real" object as there is no dereference operator like *x. So to do a deep copy, you need a function: clone(). And both Java and C# wrapped that function into an interface.
It's the issues of final type and of cascading the clone operation through the super classes which is not addressed by copy constructors - they are not extensible. But the Java clone mechanism is widely considered badly broken too; especially problems where a subclass does not implement clone(), but inherits from a superclass that implements cloneable.
I strongly recommend you research cloning carefully, whatever path you choose - you will likely choose the clone() option, but make sure you know exactly how to do it properly. It's rather like equals() and hashCode() - looks simple on the surface, but it has to be done exactly right.
I think you haven't get the right point. I give you my two cents.
Fundamentally there's a problem: creating a clone of a class without knowing the exact class type. If you use copy constructor, you cannot.
Here is an example:
class A {
public A(A c) { aMember = c.aMember }
int aMember;
}
class B : A {
public B(B c) : base(c) { bMember = c.bMember }
int bMember;
}
class GenericContainer {
public GenericContainer(GenericContainer c) {
// XXX Wrong code: if aBaseClass is an instance of B, the cloned member won't
// be a B instance!
aBaseClass = new A(c.aBaseClass);
}
A aBaseClass;
}
The Clone method, if declare virtual, could create the right class instance of the generic member.
An this problem is common to every language, C# C++ or Java...
Maybe this is what you was meaning, but I cannot understand this from any answer.
Just wanted to add that in Java the copy constructor is not completely useless.
There are cases where your class has a private instance variable of a mutable non-final type, e.g. Date, and has a setter and getter for the variable. In the setter, you should make a copy of the given date, because the caller could modify it later and thereby manipulate your object's internal state (usually by accident, but maybe intentional). In the getter, the same precaution is required.
The defensive copy could be implemented by calling clone() (the class Date is cloneable), but a malicious caller could call the setter with a subclass of Date which overrides the clone() method with {return this;}, and so the caller might still be able to manipulate your object. This is where the copy constructor comes into play: By calling new Date(theDate), you are sure to get a fresh Date instance with the same timestamp as the given date, without any connection between the two date instances. In the getter, you could use the clone method, because you know the private variable will be of class Date, but for consistency, usually the copy constructor is used there, too.
Also note that the copy constructor would note be required if the Date class was final (calling clone() were safe) or immutable (no copy required).
I think its only because once u have defined a copy constructor, you could never pass the reference itself again. (Unless it would have a function that does that...but thats not any easier than using the clone() method.)
In C++ its not a problem: you can pass the whole object or its reference.