What would be the way I could add every new instan...
# getting-started
m
What would be the way I could add every new instance of
Foo
to the
instances
map under their
pointer
property?
Copy code
abstract class Foo {
    companion object {
        val instances = mutableMapOf<CPointer<out CPointed>, Foo>()
    }

    open val pointer: CPointer<out CPointed> = something()
}

class Buzz : Foo() {
    override val pointer: CPointer<out CPointed> = somethingElse()
}
I've tried adding
Copy code
init {
    instances[this.pointer] = this
}
to the
Foo
class, but I get an error (Variable 'pointer' must be initialized) and a warning (Leaking 'this' in constructor of non-final class Foo) (and yes, I do need this...)
y
You can turn the pointer into a constructor parameter like so:
Copy code
abstract class Foo(val pointer: CPointer<out CPointed> = something())
Then the init block approach would work I think
m
@Youssef Shoaib [MOD] Just tried it and IntelliJ still argues that I'm leaking
this
(but I think it would be OK to suppress it this case) I sadly omitted one extra class, which causes the need to make
pointer
still be
open
as it extends
Buzz
, so my actual code is
Copy code
abstract class Foo {
    companion object {
        val instances = mutableMapOf<CPointer<out CPointed>, Foo>()
    }

    open val pointer: CPointer<out CPointed> = something()

    init {
        instances[this.pointer] = this
    }
}

class Buzz : Foo(someArgument: SomeType = someValue) {
    override val pointer: CPointer<out CPointed> = somethingElse()
}

class FooBar : Buzz {
    override val pointer: CPointer<out CPointed> = somethingEvenDifferent()
}
and after the modification you suggested, I got to this:
Copy code
abstract class Foo(open val pointer: CPointer<out CPointed> = something()) {
    companion object {
        val instances = mutableMapOf<CPointer<out CPointed>, Foo>()
    }

    init {
        instances[this.pointer] = this // Accessing non-final property pointer in constructor; Leaking 'this' in constructor of non-final class Foo
    }
}

class Buzz : Foo(someArgument: SomeType = someValue) {
    override val pointer: CPointer<out CPointed> = somethingElse()
}

class FooBar : Buzz {
    override val pointer: CPointer<out CPointed> = somethingEvenDifferent()
}
y
That looks alright I think. The warnings are annoying, but in this case it should be safe to ignore them. Just note that if a pointer of an object is expected to change through its lifetime, then you'll obviously run into issues
gratitude thank you 1
m
Hopefully, it won't change 😌
a
also, looks like you don't really need to override the pointer property, just assign it on construction, implementation remains the same and the warning goes away as well
m
@andylamax Do you mean adding it as a constructor argument? Well I can't do that as what I'm building is going to be a public library. And there is no meaningful way to make two constructors
a
something like this
Copy code
abstract class Foo(val pointer: CPointer<out CPointed>) {
     companion object {
         val instances = mutableMapOf<CPointer<out CPointed>, Foo>()
     }
 
     init {
         instances[this.pointer] = this
     }
 }
 
 class Buzz : Foo(something())
 
 class FooBar : Foo(somethingElse())
sorry if the formating is poor. I am on mobile
m
I need the
FooBar
class to extend the
Buzz
class 😄
Meaning I'd have to add the constructor argument to the
Buzz
class too
a
ooooh I see, then in that case you really do need the pointer to be open
👍 1
m
Well, this doesn't look good 😅 (
Window
is
Buzz
and
ApplicationWindow
is
FooBar
) Whenever I try to create a new instance of
ApplicationWindow
, the pointer that is saved there is
null
, if I try to retrieve the
pointer
property after initialization, it's not
null
Yes, I love when I break null-safety 😂
Fixed it with keeping the
pointer
as an argument, making the constructor
internal
and creating a builder function 😌