I am reading through the Qt scripting documentation and came across this passage.
Note that, even though it is not considered good practice, there is
nothing that stops you from choosing to ignore the default constructed
(this) object when your function is called as a constructor and
creating your own object anyway; simply have the constructor return
that object. The object will "override" the default object that the
engine constructed
I am confused as to what this means. What it means by 'this' object and the constructor object. Does this mean it is favored to have a this object rather than having a constructor?
Could some please explain.
Let's take the example from the Qt documentation:
function Book(isbn) {
this.isbn = isbn;
}
The constructor Book() adds an isbn property to the this object, which is returned automatically (i.e. without an explicit return statement). However, you are free to return your own object from a constructor, e.g. you could do
function Book(isbn) {
return {isbn : isbn};
}
In the latter case, you ignore the this object, create a new object and return it instead.
Related
If an object is created inside a function and the function returns that type of oject how is the memory handled.
Example:
Public Function GetEmployee(employeeid as integer) as employee
Dim oEmployee as new employee
oEmployee.FirstName="Bob"
...
...
return oEmployee
end function
Does the variable that receive the object still a pointer to the memory location that was used inside the function?
What about when you do a oEmployee2=oEmployee
Is oEmployee2 just a pointer? And any changes to oEmployee will now affect the other. Just trying to understand it from a memory perspective and how that scope works
Thanks
Assuming employee is a reference type (e.g. any class) the method will return a reference (similar in concept to a pointer in unmanaged languages) to the object instance (usually on the heap). Since only one object instance exists, all changes to it will affect the instance.
If employee is a value type (e.g any struct or primitive type) a separate copy of the instance is returned.
Assuming oEmployee is a reference type (not a struct), if you pass it as an argument, then you are passing the reference. In .NET you should think in terms of Reference types vs Value types.
This article really helped me understand how memory is allocated when I was starting out.
http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx
Ok, ObjectUtil.copy is a good technique for copying Objects. But after having a lot of problems using it to copy other classes, I guess it is not the solution I'm after.
How would you approach the copying/cloning of instances of a class that you've defined? Maybe defining a function withing the class to copy it?
It is cool that most variables are passed by reference in flex, but sometimes is annoying not having control over this (sorry, I'm too used to plain C).
Thanks!
UPDATE:
To be more precise, as I can't make the ObjectUtil.copy() work with a custom class is... is there a way to copy, by using serialization, a custom class? Did you use successfully a ByteArray copy with a custom class?
Thanks for all the replies.
If you determine that implementing a clone interface is not the correct approach in your situation, I suggest looking at the ByteArray object. I haven't used it myself, but it appears to give you all the control you should need over individual bytes. You can reading and writing from and to any object.
Senocular does a quick overview of it here.
function clone(source:Object):* {
var copier:ByteArray = new ByteArray();
copier.writeObject(source);
copier.position = 0;
return(copier.readObject());
}
Good luck!
ObjectUtil.copy uses ByteArray internally to create a copy. In order for the copy to be successful, ByteArray requires that the flash player will be aware of you custom class. You do that by registering your class using the global registerClassAlias method.
For example:
//one time globally to the application.
registerClassAlias(getQualifiedClassName(CustomClass), CustomClass);
//then
var c1:CustomClass = new CustomClass();
c1.name = "customClass";
var c2:CustomClass = ObjectUtil.copy(c1);
trace(ObjectUtil.toString(c1))
trace(ObjectUtil.toString(c2))
If you have control over the whole class hierarchy, I recommend implementing a clone() interface in every class. It's tedious, but will pay off as complexity increases.
(Forgive me if the syntax is a bit off, it's been a while)
// define a "cloneable" interface
public interface ICloneable {
function clone() : Object;
}
For every class, implement the method...
public class MyClass1 implements ICloneable {
...
public function clone() : Object {
var copy:MyClass1 = new MyClass1();
// copy member variables... if it is a user-defined object,
// make sure you call its clone() function as well.
return copy;
}
}
To create a copy of the object, simply invoke the clone() function.
var copy:MyClass1 = original.clone();
As a side note, both Java and .NET seem to have adopted the clone methods on their base Object classes. I know of no analogous method for ActionScript's Object class.
Two common idioms:
a clone method
a copy constructor
Both of these let you define what exactly making a copy means--you may want some things copied shallowly and others deeply.
Why is the FxCop rule CA1061 a bad idea?
The docs state that this rule should not be suppressed. If I have class like so:
public class Set<T>
{ List<T> m_backingList;
public bool Contains(T value)
{
return m_backingList.Contains(value);
}
}
then I add a specific implementation like this:
public class CaseInsensitiveSet : Set<String>
{
public bool Contains(object value)
{
string stringValue = value as string;
if (stringValue == null)
return false;
return base.Contains(stringValue);
}
}
the FxCop complains, but I'm not certain why this is such a bad idea. Is there some problem I don't see with this implementation?
The rule states why you're getting the message:
A method in a base type is hidden by
an identically named method in a
derived type when the parameter
signature of the derived method
differs only by types that are more
weakly derived than the corresponding
types in the parameter signature of
the base method.
In your child class, the Contains method takes an object which is more weakly typed than string and therefore hides the parent.
The reason you're getting the warning from FxCop is that this might not be an intentional design choice (since you're not overriding anything or using the new keyword).
Even if it is an intentional design choice, I would argue that it's not necessarily a good one. If you already know that the collection is going to contain strings and nothing else, why would you provide a Contains method that takes anything other than a string? It may appear that you're adding flexibility into the design but, in the end, you're really only going to confuse other developers.
There are also other naming options instead of calling the method Contains which wouldn't hide (intentionally or not) the base Contains method.
Ask yourself: do I want the users to be able to call the base class method on an instance of the derived class.
If the answer is yes: don't hide the base method, as this will make it more cumbersome to use it.
If the answer is no: don't derive from this class, or else they can still access the base method by casting the object to the base class.
http://msdn.microsoft.com/en-us/library/ms182143(VS.80).aspx
A method in a base type is hidden by
an identically named method in a
derived type when the parameter
signature of the derived method
differs only by types that are more
weakly derived than the corresponding
types in the parameter signature of
the base method.
EDIT
Basically you're hiding the base method (public bool Contains in Set), which will never now be run in preference to the derived method. But the derived method is more weakly defined than the base method so there are situations when the base method is the preferable method.
I know that in C# when you pass an object (non primitive) to a method the following is true:
A reference to the object is passed
Changes made to the object in the method are reflected outside of the method.
Also, you can pass a reference to a reference in C# e.g this.changeObject(ref myObject);, in which case:
Changes to the object and also to the ref are reflected outside of the method e.g. myObject = new new List(); would change the passed objects referred location.
My question:
Is this possible to do in Flex/Actionscript - can a ref keyword be used?
No, you cannot. ActionScript doesn't have a ref keyword or a similar (double pointer like) concept. You always pass object references to functions (except for primitives) and modifications are reflected back.
I want to extend the FileReference class of Flex to contain a custom property. I want to do this because AS3 doesn't let me pass arguments to functions through event listeners, which makes me feel sad, so I need this property to exist on the event target, so I can access it.
I also want to be able to cast extant FileReference objects to this class without any fuss. I have:
var fr:SmxFR = e.target as SmxFR
and I want that to work; right now it just returns null.
A blank, newly instantiated SmxFR object has the extended property in place, but all of its inherited properties and objects return Error: Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
This is the class I am using, SmxFR.as:
package
{
import flash.net.FileReference;
public class SmxFR extends FileReference
{
public var housenum:String = "";
public function SmxFR()
{
super();
}
}
}
Kept it as straightforward as I could, really. Can someone please help me figure this out? Thanks.
Edit:
Per request, this is the instantiation which results in the aforementioned error in all inherited objects:
var fr:SmxFR = new SmxFR();
I get living handle property from that, and all other (that is, inherited) properties throw Error #2037.
So, maybe what I want to do is going to require overriding FileReferenceList? If the original objects must be instantiated to SxmFR, that's what I'll have to do, since I'm using FRL to allow the user to select multiple files at once. Are you guys sure there is no way to fast from a FileReference to my class?
You can totally pass objects via event listeners, it's just done in a specific way. I'd learn to do it correctly, rather than trying to extend a core library which could cause you problems later if you make a small mistake.
My solution: instead of extending FileReference, extend Event and add your properties to that.
var myEvent:MyExtendedEvent = new MyExtendedEvent();
myEvent.myCustomProperty = myValue;
dispatchEvent(myEvent);
Then in your handler you just write:
function myEventHandler(e:MyExtendedEvent):void {
trace(e.myCustomProperty);
}
Much more painless to go down this road! The added benefit is that if any other Flash Developer anywhere ever looks at your code they're not going to get hit in the face with a non-standard customized FileReference. :)
When e.target is instantiate as FileReference you can't cast it to SmxFR because it's not in the line of inheritance. In the other way you can a SmxFR Object to FileRefernce.
Extending FileReferenceList is not going to be helpful. FileReferenceList.browse() method creates an array of FileReference object when user selects multiple files - that happens internally (may be in its private methods) and you cannot change that behavior and force it to create SxmFR objects instead. Use custom events as Myk suggested.
This article talks about Sound objects, but may be that's applicable to FileReference objects too. May be you cannot reuse them. Post the code where you use the SmxFr class and get the said error.