auto_gcroot class does not have public indirection operator(operator*).
However, code sample below has been successfully compiled. Why is so?
auto obj = *(std::static_pointer_cast<const auto_gcroot<Object^>>(pObj))
std::static_pointer_cast returns a std::shared_ptr (In this case, a std::shared_ptr<const auto_gcroot<Object^>>), which does have an operator*.
*std::static_pointer_cast<T>(pObj) is an lvalue of type T, so obj will be a copy of the auto_gcroot<Object^> object stored by the shared_ptr.
I have a Kotlin class with a member object:
private var strings = object { var foo = ""; var bar = "" }
Inside my class's functions, I can reference strings.foo and strings.bar.
But when I make strings a public var, suddenly all of its members become "unresolved references". Why?
class Foo {
// Making this `private` fixes the errors below for some reason
public var strings = object {
var foo = ""
var bar = ""
}
fun initialize() {
strings.foo = getFoo() // "Unresolved reference: foo"
strings.bar = getBar() // "Unresolved reference: bar"
}
}
(What I'm trying to do here is expose a whole bunch of string resources as constants so I don't have to use the literal string values throughout my code. I'm actually using lateinit var for each member but that doesn't change the result here.)
strings is defined with an object literal. You probably want to use an regular object declaration instead:
object Strings {...}
strings = Strings()
With the object literal, strings is an anonymous object whose type is "usable (and visible) only in the scope where it is declared".
without any explicitly declared supertype, menaing Any is implicit super type of this object.
When you make strings a public var, it escapes the current scope and is implicitly downcasted to its supertype; without any explicitly declared supertype, the supertype is Any, so of course you get errors trying to reference the properties foo and bar.
From Kotlin spec
The main difference between a regular object declaration and an anonymous object is its type. The type of an anonymous object is a special kind of type which is usable (and visible) only in the scope where it is declared. It is similar to a type of a regular object declaration, but, as it cannot be used outside the declaring scope, has some interesting effects.
When a value of an anonymous object type escapes current scope:
If the type has only one declared supertype, it is implicitly downcasted to this declared supertype;
If the type has several declared supertypes, there must be an implicit or explicit cast to any suitable type visible outside the scope, otherwise it is a compile-time error.
Note: an implicit cast may arise, for example, from the results of type inference.
Note: in this context “escaping current scope” is performed immediately if the corresponding value is declared as a non-private global- or classifier-scope property, as those are parts of an externally accessible interface.
You could also use a Companion object:
companion object Strings {
var foo = ""
var bar = ""
}
fun init(){
foo = getFoo()
bar = getBar()
}
When I do this
val data = object {
val field = 5
}
fun main(){
println(data.field) // throws
}
It throws Unresolved reference: field.
But all of this is ok:
val field = 6
class Data(val field: Int = 7)
val data7 = Data()
fun main(){
val data4 = object {
val field = 4
}
println(field) // ok
println(data4.field) // ok
println(data7.field) // ok
}
I do not get it, why Kotlin does not let me use properties from top-level objects? I thought that object is just like class object, but anonymous (without class) and there should be no difference between data and data7 in examples above. But it seems that there is difference.
This is documented in the "Object Literals" section of the Language Specification, about the difference between object declarations and anonymous objects (the things that object literals create).
The main difference between a regular object declaration and an anonymous object is its type. The type of an anonymous object is a special kind of type which is usable (and visible) only in the scope where it is declared. It is similar to a type of a regular object declaration, but, as it cannot be used outside the declaring scope, has some interesting effects.
Your data here is considered to have escaped the declaring scope of "the top level of the file", because it is public. You can access it from the top level scopes of other files.
Note: in this context “escaping current scope” is performed immediately if the corresponding value is declared as a non-private global- or classifier-scope property, as those are parts of an externally accessible interface.
Marking it private would have fixed it. The reason for the error is that:
When a value of an anonymous object type escapes current scope:
If the type has only one declared supertype, it is implicitly downcasted to this declared supertype;
If the type has several declared supertypes, there must be an implicit or explicit cast to any suitable type visible outside the scope, otherwise it is a compile-time error.
Here, the super type is implicitly Any, so the type of data is Any, and obviously there is no field on the type Any.
On the other hand, data4 have not escaped the current scope, because it is local to the main function's statement scope. You can't access it from another scope.
See also the great example from the spec.
As I know Java is pass-by-value from this post. I am from Java background I wonder what Kotlin is using for passing values in between. Like in Extensions or Methods etc.
Every time I hear about the "pass-by-value" vs "pass-by-reference" Java debate I always think the same. The answer I give: "Java passes a copy (pass-by-value) of the reference (pass-by-reference)". So everyone is happy. I would say Kotlin does the same as it is JVM based language.
UPDATE
OK, so it's been a while since this answer and I think some clarification should be included. As #robert-liberatore is mentioning in the comments, the behaviour I'm describing is true for objects. Whenever your methods expect any object, you can assume that the JVM internally will make a copy of the reference to the object and pass it to your method. That's why having code like
void doSomething(List<Integer> x) {
x = new ArrayList<Integer>()
}
List<Integer> x = Arrays.asList(1, 2, 3);
doSomething(x);
x.length() == 3
behaves like it does. You're copying the reference to the list, so "reassigning it" will take no effect in the real object. But since you're referring to the same object, modifying its inner content will affect the outer object.
This is something you may miss when defining your attributes as final in order to achieve immutability. You won't be able to reassign them, but there's nothing preventing you from changing its content
Of course, this is true for objects where you have a reference. In case of primitives, which are not a reference to an object containing something but "something" themselves, the thing is different. Java will still make a copy of the whole value (as it does with the whole reference) and pass it to the method. But primitives are just values, you can't "modify its inner values". So any change inside a method will not have effect in the outer values
Now, talking about Kotlin
In Kotlin you "don't have" primitive values. But you "do have" primitive classes. Internally, the compiler will try to use JVM primitive values where needed but you can assume that you always work with the boxed version of the JVM primitives. Because of that, when possible the compiler will just make a copy of the primitive value and, in other scenarios, it will copy the reference to the object. Or with code
fun aJvmPrimitiveWillBeUsedHere(x: Int): Int = x * 2
fun aJvmObjectWillBeUsedHere(x: Int?): Int = if (x != null) x * 2 else 1
I'd say that Kotlin scenario is a bit safer than Java because it forces its arguments to be final. So you can modify its inner content but not reassign it
fun doSomething(x: MutableList<Int>) {
x.add(2) // this works, you can modify the inner state
x = mutableListOf(1, 2) // this doesn't work, you can't reassign an argument
}
It uses the same principles like Java. It is always pass-by-value, you can imagine that a copy is passed. For primitive types, e.g. Int this is obvious, the value of such an argument will be passed into a function and the outer variable will not be modified. Please note that parameters in Kotlin cannot be reassigned since they act like vals:
fun takeInt(a: Int) {
a = 5
}
This code will not compile because a cannot be reassigned.
For objects it's a bit more difficult but it's also call-by-value. If you call a function with an object, a copy of its reference is passed into that function:
data class SomeObj(var x: Int = 0)
fun takeObject(o: SomeObj) {
o.x = 1
}
fun main(args: Array<String>) {
val obj = SomeObj()
takeObject(obj)
println("obj after call: $obj") // SomeObj(x=1)
}
You can use a reference passed into a function to change the actual object.
The semantics is identical to Java.
In Java, when you have an instance of an object, and you pass it to a method, that method can change the state of that object, and when the method is done, the changes would have been applied to the object at the call site.
The same applies in Kotlin.
For primitives value is passed, and for non-primitives a reference to the object is passed. I'll explain with an example:
The code:
fun main() {
var a = 5
var b = a
a = 6
println("b = $b")
}
prints: b = 5
Kotlin passes the value of a to b, because a is a primitive. So changing a afterwards won't impact b.
The code:
fun main() {
var a = Dog(5)
var b = a
a.value = 6
println("b = ${b.value}")
}
class Dog (var value: Int)
prints b = 6, because this time a is not a primitive and so the reference to the object (Dog) was passed to b and not its value. Therefore changing a would affect all objects that point to it.
In Java primitive types like int, float, double, boolean are passed to a method by value, if you modify them inside the receiver method they doesn't change into the calling method. But if the property/variable type isn't a primitive, like arrays of primitives or other classes when they are changed inside the method that receive them as parameter they also change in the caller method.
But with Kotlin nothing seems to be primitive, so I think all is passed by reference.
This might be a little bit confusing.
The correct answer, IMHO, is that everything passes by reference, but no assignment is possible so it will be similar to passing by value in C++.
Note that function parameters are constant, i.e., they cannot be assigned.
Remember that in Kotlin there are no primitive types. Everything is an object.
When you write:
var x: Int = 3
x += 10
You actually create an object of type Int, assign it the value 3, and get a reference, or pointer, named x.
When you write
x += 10
You reassign a new Int object, with the value 13, to x. The older object becomes a garbage (and garbage-collected).
Of course, the compiler optimizes it, and creates no objects in the heap in this particular case, but conceptually it is as explained.
So what is the meaning of passing by reference function parameters?
Since no assignment is possible for function parameters, the main advantage of passing by reference in C++ does not exist in Kotlin.
If the object (passed to the function) has a method which changes its internal state, it will affect the original object.
No such method exists for Int, String, etc. They are immutable objects.
No copy is ever generated when passing objects to functions.
Bear in mind, am quite new to Kotlin. In my opinion, primitives are passed-by-value, but objects are passed-by-reference.
A primitive passed to a class works by default, but if you pass an object from a list, for example, and that object changes, the class object changes too. Because, in fact, it is the same object.
Additionally, if objects gets removed from the list, the class object IS STILL A REFERENCE. So it can still change due to references in other places.
Example below explaines. You can run it here.
fun main() {
val listObjects = mutableListOf(ClassB(), ClassB(), ClassB())
val listPrimitives = mutableListOf(111, 222, 333)
val test = ClassA()
test.ownedObject = listObjects[0]
test.ownedPrimitive = listPrimitives[0]
println("ownedObject: " + test.ownedObject.isEnabled +", ownedPrimitive: " +
test.ownedPrimitive)
listObjects[0].isEnabled = true
println("ownedObject: " + test.ownedObject.isEnabled +", ownedPrimitive: " +
test.ownedPrimitive)
listPrimitives[0] = 999
println("ownedObject: " + test.ownedObject.isEnabled +", ownedPrimitive: " +
test.ownedPrimitive)
}
class ClassA {
var ownedObject: ClassB = ClassB()
var ownedPrimitive: Int = 0
}
class ClassB {
var isEnabled = false
}
Since Kotlin is a new language for JVM, like Java it is pass-by-value. The confusing part is with object, at first it looks like that it is passed-by-reference but the actuality is that the reference/pointer itself is pass-by-value (a copy of a reference is passed to a method) hence when a method receives a reference to an object, the method can manipulate the original object.
I'm facing a problem and studying the OCaml documentation did not enable me to find a satisfying solution yet.
The following snippet illustrates my problem:
class A = object (self)
(* this should not be overwrittable in subclass B, but callable
on objects of type B!
*)
method dangerous_one input =
(do dangerous stuff...)
let safe_output = safe_dangerous_one input in
(... more dangerous things done with safe_output ...)
(* This is safe, should be overwrittable and callable in subclass *)
method safe_dangerous_one input = (...)
end
class B = object(self) inherit A as super
method! safe_dangerous_one input = (* subclass behaviour ... *)
end
To sum up the snippet: class A is base class to subclass B.
It has a dangerous method that is complex and has some dark corners I don't want client code to have to deal with.
In fact, I want to prohibit subclasses from overwriting method "dangerous_one".
Instead, they should overwrite the function "safe_dangerous_one".
Furthermore, it should be possible to CALL "b#dangerous_one" where "b : B" which uses the (new) definition of the "safe_dangerous"-parts as specified in class B.
My dilemma appears to be: if I simply make method "dangerous_one" private, nothing keeps the client code in class B from overwriting it, potentially even making it public.
If I hide its implementation from the signature, it can not be overwritten anymore, but I cannot call "b#dangerous_one" anymore - the code becomes inaccessible to calls also.
Is there any way to achieve what I aim to do?
Best,
Nablezen
If I hide its implementation from the signature, it can not be overwritten anymore, but I cannot call "b#dangerous_one" anymore - the code becomes inaccessible to calls also.
You can, you just need to make it private, you can't hide public methods:
class type safe = object
method safe_dangerous_one : in_channel -> int
end
class a : safe = object (self)
method private dangerous_one input = input_binary_int input
method safe_dangerous_one input =
max 255 (self#dangerous_one input)
end
class b parameters = object(self)
inherit a parameters as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end
If you want unsafe method to be accessible, but not overridable, then just re-publish it at another name (kind of NVI):
class type safe = object
method unsafe_dangerous_one : in_channel -> int
method safe_dangerous_one : in_channel -> int
end
class a : safe = object (self)
method private dangerous_one input = input_binary_int input
method unsafe_dangerous_one input = self#dangerous_one input
method safe_dangerous_one input =
max 255 (self#dangerous_one input)
end
class b = object(self)
inherit a as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end
And a piece of free advice. In other languages, classes and methods are used as a tool for structuring programs, because they have no better tools. In OCaml you have first class functions, records, structures, etc. So it is better to use a proper tool for at each situation. When you design a class, you should understand, that the method by its original definition (not spoiled by C++/Java/Python/etc) is something overridable. A method is an operation that has an implementation that varies across some genera. So, if you define something as a method, and then trying hard to prevent people from overriding it, then chances are high that you're doing something wrong. If you don't want it to be overridable, then just don't define it as a method at all. In your case you should put dangerous_one operation into a let-bound function. You can bound it in the context of the class, so that you will have an access to all parameters, or you can bind it on a toplevel, the choice is yours:
class a parameters =
let dangerous_one input = input_binary_int input in
object (self)
method safe_dangerous_one input =
max 255 (dangerous_one input)
end
class b = object(self)
inherit a as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end
Also, a very good source of documentation about OCaml class system is Jason Hickey's Introduction to Objective Caml. It is slightly outdated, but is still very good.