I want to make a global vector of my own object class called "Person". However, the compiler says that
error C2039: '{dtor}' : is not a member of 'System::IDisposable'
1> c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable'
So I looked up how to implement IDisposable (which I now know is used primarily for unmanaged resources) but still can't seem to implement it with the following:
ref class Globals : System::IDisposable
{
public:
static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
void Dispose()
{
delete person_data;
}
};
The 2 errors I get are:
error C2605: 'Dispose' : this method is reserved within a managed class
1> did you intend to define a destructor?
error C3766: 'Globals' must provide an implementation for the interface method 'void System::IDisposable::Dispose(void)'
1> c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable::Dispose'
You don't have to explicitly derive from IDisposable. Following the MSDN doco, use the following pattern:
ref class Globals
{
public:
static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
!Globals() // finalizer
{
delete person_data;
{
protected:
~Globals() // destructor calls finalizer
{
this->!Globals();
}
};
Use a destructor. In C++/CLI ~ClassName() is Dispose() and !ClassName() is equivalent to C#'s ~ClassName(). In your case:
ref class Globals : System::IDisposable
{
public:
static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>;
void ~Globals()
{
delete person_data;
}
};
use a finalizer as shown at http://www.codeproject.com/KB/mcpp/cppclidtors.aspx
You don't need to implement Dispose() yourself, either directly or via a destructor. The implicitly-generated destructor already destroys all member objects. The IDisposable interface will be added automatically, don't mention it explicitly.
Next, you need to make up your mind whether person_data is a handle (which has to be set to an instance created with gcnew) or member object semantics (like stack semantics, the constructor is automatically called by the constructor of the parent object, the destructor called automatically when the lifetime of the parent object ends, and you use "." instead of "->" to access members).
Also, are you sure you want one copy of person_data shared between all instances of "Globals", but destroyed by the first instance to be disposed, leaving any other instances holding an invalid reference (reference to disposed object)? It looks like you're trying to use a Singleton anti-pattern here, is that correct?
From C++/CLI in Action The C++/CLI Dispose pattern has these rules (paraphrased):
If a class has a finalizer or a
destructor the compiler generates
Dispose(bool) that will call either
the finalizer or destructor based on
the bool value.
If it has just a d'tor (~type) then the compiler calls
Dispose(true) so the d'tor is called.
If it has just a finalizer (!type)
then the compiler calls
Dispose(false) so the finalizer is
called
Also for the second rule: The compiler will implement the IDisposable interface for you (by generating Dispose()). It then uses SuppressFinalize to make sure the finalizer isn't called.
I did this to your code and the only way I could get it to compile was to make person_data a instance member. The error i got when it was static was error C2039: '{dtor}' : is not a member of 'System::IDisposable' which doesn't make much sense.
Also, do you even need to delete the person_data vector since is a managed object? Maybe you do but I haven't used the cliext enough to say.
Edit Perhaps the first paragraph of this article has the answer (emphasis mine):
When you declare a member variable as
static and when the application
starts, the compiler creates a copy of
that member. This member would be
maintained by the compiler while the
program is running. If you declare an
instance of a class, like the above
vehicle variable, the static member is
not part of the object: the compiler
creates and maintains the static
member, whether you use it or not,
whether you declare a class variable
or not.
Related
It means that, by the time of the base class constructor execution, the properties declared or overridden in the derived class are not yet initialized. If any of those properties are used in the base class initialization logic (either directly or indirectly, through another overridden open member implementation), it may lead to incorrect behavior or a runtime failure. When designing a base class, you should therefore avoid using open members in the constructors, property initializers, and init blocks.
I was studying Inheritence from Kotlin docs, and I got stuck here. There was another post which asked a question about this, but the answers were just what the docs said in a different way.
To be clear, I understood the data flow between constructors and inheritence. What I couldn't understand was how we can use an overridden property in a base class initialization. It says
It could happen directly or indirectly
What does this actually mean? How can the base class can somehow access to the overridden property in the derived class?
Also, it said
You should therefore avoid using open members in the constructors,
property initializers and init blocks.
So how can we properly use open properties?
EDIT FOR THE COMMENT:
fun main ()
{
val d = Derived("Test2")
}
open class Base()
{
open val something:String = "Test1"
init
{
println(something) //prints null
}
}
class Derived(override val something: String): Base()
What does this actually mean? How can the base class can somehow access to the overridden property in the derived class?
This is one direct way:
abstract class Base {
abstract val something: String
init {
println(something)
}
}
class Child(override val something: String): Base()
fun main() {
Child("Test") // prints null! because the property is not initialized yet
}
This prints null, which is pretty bad for a non-nullable String property.
You should therefore avoid using open members in the constructors, property initializers and init blocks.
So how can we properly use open properties?
You can use these properties in regular methods on the base class (or in custom property getters):
abstract class Base {
abstract val something: String
fun printSomething() {
println(something)
}
}
class Child(override val something: String): Base()
fun main() {
Child("Test").printSomething() // correctly prints "Test"
}
EDIT: Here are some clarifications regarding the follow-up questions in the comments.
I couldn't quite get why the code in the init block went for the parameter in the child class constructor
I think you might be confused by Kotlin's compact syntax for the primary constructors in general, which probably makes the debugger's flow hard to understand. In the Child declaration, we actually declare many things:
the argument something passed to the Child's primary constructor
the property something on the Child class, which overrides the parent's one
the call to the parent constructor (Base())
When Child() is called, it immediately calls the Base() no-arg constructor, which runs the init block.
We didn't even delegate the base constructor with a parameter or anything, but it still went for the parameter who did the overriding
You might be mixing declarations and runtime here. Although we declare things in the Base class and in the Child class, there is only 1 instance at runtime (an instance of Child) in this example code.
So, in fact, there is only 1 property called something here (only one place in memory). If the init block accesses this property, it can only be the property of the child instance. We don't need to pass anything to the Base constructor because the init block is effectively executed with the data/fields of the Child instance.
Maybe you would be less confused if you saw the Java equivalent of this. It's obvious if you think of the abstract something as a declaration of a getter getSomething(). The child class overrides this getSomething() method and declares a private something field, the getter returns the current value of the field something. But that field is only initialized after the constructor of the parent (and the init block) finished executing.
I am learning Kotlin programming language perfectly. I try to write code in different patterns and try to understand. However, I did not understand the thing. Can you help me, please?
Here it is:
open class Parent {
open val foo = 1
init {
println(foo)
}
}
class Child: Parent() {
override val foo =2
}
fun main() {
Child()
}
In this code, 0 is the output. How will this be?
This is about the order of construction — and is a subtle gotcha that's easy to fall prey to. (I'm afraid this answer is a bit long, but the issues here are well worth understanding.)
There are a few basic principles colliding here:
Superclass initialisation happens before subclass initialisation. This includes code in constructors, code in init blocks, and property initialisers: all of that happens for a superclass before any in a subclass.
A Kotlin property consists of a getter method, a setter method (if it's a var), and a backing field (if needed). This is why you can override properties; it means that the accessor method(s) are overridden.
All fields initially hold 0/false/null before they get initialised to any other value. (Normally, you wouldn't get to see that, but this is one of those rare cases. This differs from languages like C where if you don't explicitly initialise a field it can hold random values depending on what that memory was previously used for.)
From the first principle, when you call the Child() constructor, it will start off by calling the Parent() constructor. That will set the superclass's foo field to 1, and then get the foo property and print it out. After that, the Child initialisation happens, which in this case is simply setting its foo field to 2.
The gotcha here is that you effectively have two foos!
Parent defines a property called foo, and that gets accessor methods and a backing field. But Child defines its own property called foo, overriding the one in Parent — that one overrides the accessor methods, and gets its own backing field as well.
Because of that override, when the Parent's init block refers to foo, it calls the getter method which Child overrides, to get the value of Child's backing field. And that field hasn't been initialised yet! So, as mentioned above, it's still holding its initial value of 0, which is the value that the Child getter returns, and hence the value that Parent constructor prints out.
So the real problem here is that you're accessing the subclass field before it's been initialised. This question shows why that's a really bad idea! As a general rule:
A constructor/initialiser should never access a method or property that could be overridden by a subclass.
And the IDE helps you out here: if you put your code into IntelliJ, you'll see that the usage of foo is marked with the warning ‘Accessing non-final property foo in constructor’. That's telling you that this sort of problem is possible.
Of course, there are more subtle cases that an IDE might not be able to warn you about, such as if a constructor calls a non-open method that calls an open one. So care is needed.
There are occasions when you might need to break that rule — but they're very rare, and you should check very carefully that nothing can go wrong (even if someone comes along later and creates a new subclass). And you should make it very clear in comments/documentation what's going on and why it's needed.
Now, let's with java understand why. In Java, it's impossible to override fields and under the hood in Kotlin is the same. When you override a property, in fact, you override a getter, not a field. For instance, you can override a property that doesn't have a field with a property that has a field. That's totally legal. However, when both a property from a superclass and an overridden property in a subclass have fields, that might lead to unexpected results. Let's see what bytecode is generated for the Kotlin class in my example. As usual, I'll look at the corresponding Java code instead for simplicity.
public class Parent {
private final int foo = 1;
public int getFoo() {return foo;}
public Parent(){
System.out.println(getFoo());
}
}
public final class Child extends Parent {
private final int foo = 2;
public int getFoo() {return foo;}
}
public class Main
{
public static void main (String[] args) {
new Child();
}
}
Note two things here. First, the foo get to is trivial, so a field and a getter correspond to the full property. Then because the property is open and can be overridden in a subclass, its usage inside the class is compiled to a getter code, not a field code. Now, the generated code for the child class. Note that the overridden property in the parent class is also compiled to a field and a getter, and now it's another field. What happens when you create an instance of the child class? At first at the parent constructor is called, the parent constructor initializes the first fulfilled with one. But inside the init section, an overridden getter is called which calls get foo from the child class. Because the field in the child class is not yet initialized, 0 is returned. That's why 0 is printed here.
Please go through following points:
Initializer Blocks i.e. init {} block are called during an instance initialization. They are called after Primary Constructor.
In above code println(foo) is placed inside init block.
Hence, the value which gets printed i.e. 0 in this case, is the value before assignment statement open val foo = 1.
If you want the output to be 1 then make following changes:
open class Parent {
open var foo : Int = 0
init {
foo = 1
println(foo)
}
}
class Child: Parent() {
override var foo =2
}
fun main() {
Child()
}
And lastly, please go through this post. This will help you in getting better understanding of this area.
How can I solve the following case?
interface I
class A(i: I)
class C : I, A(this) // << --- 'this' is not defined in this context
In short, I want to pass the class instance to super class constructor.
Is it possible in Kotlin?
P.S.
All the answers are good and technically correct. But let's give a concrete example:
interface Pilot {
fun informAboutObstacle()
}
abstract class Car(private val pilot: Pilot) {
fun drive() {
while (true) {
// ....
if (haveObstacleDetected()) {
pilot.informAboutObstacle()
}
// ....
}
}
fun break() {
// stop the car
}
}
class AutopilotCar : Pilot, Car(this) { // For example, Tesla :)
override fun informAboutObstacle() {
break() // stop the car
}
}
This example don't look too contrived, and why can't I implement it with OOP-friendly language?
No, this is not possible on the JVM. this is only available after the super class has been initialized.
From
https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.10.2.4
The instance initialization method (§2.9.1) for class myClass sees the new uninitialized object as its this argument in local variable 0. Before that method invokes another instance initialization method of myClass or its direct superclass on this, the only operation the method can perform on this is assigning fields declared within myClass.
So the bytecode instruction aload 0 to push this on the stack is forbidden before the super-class constructor is called. That's why it cannot be passed as an argument to the super-constructor.
Kotlin was born as a JVM language and aims for maximum interoperability with Java code and a minimum overhead of its language features. While Kotlin could have chosen to orchestrate object initialization in a different way, it would create problems in mixed Java-Kotlin class hierarchies and add significant overhead.
In the good tradition of OOP languages such as Java, C# or Swift, Kotlin doesn't allow you to leak the this reference before the call to superclass initialization has completed. In your special case you're just storing the reference, but in just a slightly different case the superclass code might try to use the received object, which at that point is still uninitialized.
As a specific example of why languages don't allow this, consider a case where A is a class from a library you use and this rule is not in effect. You pass this like you do and things work fine. Later you update the library to a newer version and it happens to add something as benign as i.toString() to its constructor. It has no idea it's actually calling an overridden method on itself. Your toString() implementation observes all its invariants broken, such as uninitialized vals.
This design suffers from other problems, not just the circular initialization dependency you are struggling with now. In a nutshell, the class A expects this:
But instead you create this:
The class A has a dependency on a collaborator object of type I. It doesn't expect itself as the collaborator. This may bring about all kinds of weird bugs. For example your C.toString() may delegate to super.toString() and A.toString() (A is the super of C) may call into I.toString(), resulting in a StackOverflowError.
I can't say from your question whether A is designed for extension, which would make the C : A part correct, but you should definitely disentangle A from I.
I'm attempting to create a class in Swift 3 to implement a Cordova plugin. I have this building and running, but the application crashes whenever any properties of the class are accessed. I've tried two ways of initializing the class:
#objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players = [UUID:DSFPlayerHandler] ();
...
}
and
#objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players :[UUID:DSFPlayerHandler];
override init () {
players = [:];
}
...
}
However, when my players property is used, the result is a EXC_BAD_ACCESS exception, with an address that looks like a null pointer dereference.
The object is being created by Objective C code, which is a language I have no familiarity with at all, but I think this is the line that creates it:
obj = [[NSClassFromString(className)alloc] initWithWebViewEngine:_webViewEngine];
The CDVPlugin class contains a comment stating that initWithWebViewEngine should not be overridden (and indeed I do not seem to be able to override this method, because while it is declared in the CDVPlugin.m file, it isn't mentioned in CDVPlugin.h, so the Swift compiler doesn't seem to know about it), but rather initialization code should be placed in a method called pluginInitialize instead. However, if I do that I get a compiler error ("Class DSFMediaCentre has no initializers").
Furthermore, if I put my init() method back in and set it to call pluginInitialize(), like this:
override init () {
super.init(); // necessary otherwise next line is an error
pluginInitialize();
}
override func pluginInitialize() {
players = [:];
}
the error then changes to "Property 'self.players' not initialized at super.init call".
How do I make this class initialize correctly?
You have a mismatch between the strict initialization system required by the language and the procedure used by the framework you're working with.
Swift demands that a) properties be initialized as part of object construction, and b) that construction be chained to the type's supertype. But the CDVPlugin type is doing the construction on your behalf; you don't have the ability to customize it. (This makes more sense in ObjC, because it doesn't have the same compile-time restrictions as Swift.)
The situation is similar to unpacking an object from a nib file. In that case too, because it's the nib loading system that's constructing your object, you don't have the ability to customize the initializer. Your type will always be constructed by init(coder:). In a certain sense, your initialization point moves further down, to awakeFromNib(), and among other things, that forces outlets to other objects in the archive to be declared as optional, usually implicitly unwrapped.
The same solution should avail you here. You should consider pluginInitialize() to be your initialization point. The language then requires that properties be optional, since they are not filled at its initialization point. Therefore, make the property an IUO:
#objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players :[UUID:DSFPlayerHandler]!
override func pluginInitialize() {
players = [:];
}
}
and all should be well.
The other solution is to use lazy keyword
lazy var players :[UUID:DSFPlayerHandler] = [:]
So, you don't need to initialize players in initializer but still make sure players always non-nulable
Reading this MSDN article, I came across that simple example, which is really fitted for me since I making some RAII classes over some native c++ interfaces doing the whole job: (and I do it for the first time)
ref class Wrapper {
Native *pn;
public:
// resource acquisition is initialization
Wrapper( int val ) { pn = new Native( val ); }
// this will do our disposition of the native memory
~Wrapper(){ delete pn; }
void mfunc();
protected:
// an explicit Finalize() method—as a failsafe
!Wrapper() { delete pn; }
};
This class corresponds exactly to what I have written so far. Save that I had not implemented the Finalize method. But while wondering about its peculiarity and usage, and before I can grasp it much deeper... I was wondering if it is general use and good habit to put the Finalizer method in protected scope.
The access modifier for a finalizer is essentially ignored as there are special rules for finalizers:
They can't be called directly (even from within the class itself).
When called by the system, they automatically call their base class finalizers.
Officially, the finalizer is a protected virtual method declared on Object: http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx. In C# you cannot place an accesibilty modifier on the finalizer.
In C++/cli, you can specify any access modifier, but it is essentially ignored. That is, making it public or private changes nothing: the special rules are still enforced.
So, I'd say, just continue to make it protected just based on convention.