https://kotlinlang.org logo
#getting-started
Title
# getting-started
m

Matyáš Vítek

10/26/2023, 7:51 PM
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

Youssef Shoaib [MOD]

10/26/2023, 8:04 PM
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

Matyáš Vítek

10/27/2023, 12:32 PM
@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

Youssef Shoaib [MOD]

10/27/2023, 12:33 PM
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

Matyáš Vítek

10/27/2023, 1:01 PM
Hopefully, it won't change 😌
a

andylamax

10/27/2023, 1:48 PM
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

Matyáš Vítek

10/27/2023, 2:13 PM
@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

andylamax

10/27/2023, 2:27 PM
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

Matyáš Vítek

10/27/2023, 2:29 PM
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

andylamax

10/27/2023, 2:35 PM
ooooh I see, then in that case you really do need the pointer to be open
👍 1
m

Matyáš Vítek

10/28/2023, 8:51 AM
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 😌