Class 方法在 Chapel 中接受派生 类
Class method accepting derived classes in Chapel
考虑以下代码,我希望将 class(此处为 Class2)及其派生的 classes(此处为 Class3)的实例存储在另一个 class 中的数组中(这里是 Class1)。如前所述,编译器对最后一行不满意。我做错了什么?
class Class2 {
var y : int;
}
class Class3 : Class2 {
var z : int;
}
class Class1 {
var count : int;
var x : [0..10] owned Class2?;
proc add(ref a : Class2) {
x[count] = a;
count += 1;
}
}
var C1 = new owned Class1();
var C2 = new owned Class2();
var C3 = new owned Class3();
C1.add(C2); // OK
C1.add(C3); // Compiler not happy
编译器输出:
test2.chpl:25: error: unresolved call 'owned Class1.add(owned Class3)'
test2.chpl:14: note: this candidate did not match: Class1.add(ref a: Class2)
test2.chpl:25: note: because call actual argument #1 with type owned Class3
test2.chpl:14: note: is passed to formal 'ref a: owned Class2'
$CHPL_HOME/modules/internal/Atomics.chpl:557: note: candidates are: AtomicT.add(value: T, param order: memoryOrder = memoryOrder.seqCst)
$CHPL_HOME/modules/internal/NetworkAtomics.chpl:280: note: RAtomicT.add(value: T, param order: memoryOrder = memoryOrder.seqCst)
note: and 4 other candidates, use --print-all-candidates to see them
尝试在 proc add
上使用 in
意图而不是 ref
意图:
class Class2 {
var y : int;
}
class Class3 : Class2 {
var z : int;
}
class Class1 {
var count : int;
var x : [0..10] owned Class2?;
proc add(in a : Class2) {
x[count] = a;
count += 1;
}
}
var C1 = new owned Class1();
var C2 = new owned Class2();
var C3 = new owned Class3();
C1.add(C2); // OK
C1.add(C3); // OK!
为什么这很重要?将对子 class (Class3) 的引用传递给期望对父 class (Class2) 的引用的参数不是类型安全的。特别是您可以想象将 class 指针更改为 Class2 而不是 Class3 的方法,这可能会导致调用站点出现其他错误。
我的猜测是 add
函数使用 ref
意图只是为了实现从 C3
的所有权转移。 in
intent 是一种更好的方法,它支持传递子类型(因为上述类型错误情况是不可能发生的)。
考虑以下代码,我希望将 class(此处为 Class2)及其派生的 classes(此处为 Class3)的实例存储在另一个 class 中的数组中(这里是 Class1)。如前所述,编译器对最后一行不满意。我做错了什么?
class Class2 {
var y : int;
}
class Class3 : Class2 {
var z : int;
}
class Class1 {
var count : int;
var x : [0..10] owned Class2?;
proc add(ref a : Class2) {
x[count] = a;
count += 1;
}
}
var C1 = new owned Class1();
var C2 = new owned Class2();
var C3 = new owned Class3();
C1.add(C2); // OK
C1.add(C3); // Compiler not happy
编译器输出:
test2.chpl:25: error: unresolved call 'owned Class1.add(owned Class3)'
test2.chpl:14: note: this candidate did not match: Class1.add(ref a: Class2)
test2.chpl:25: note: because call actual argument #1 with type owned Class3
test2.chpl:14: note: is passed to formal 'ref a: owned Class2'
$CHPL_HOME/modules/internal/Atomics.chpl:557: note: candidates are: AtomicT.add(value: T, param order: memoryOrder = memoryOrder.seqCst)
$CHPL_HOME/modules/internal/NetworkAtomics.chpl:280: note: RAtomicT.add(value: T, param order: memoryOrder = memoryOrder.seqCst)
note: and 4 other candidates, use --print-all-candidates to see them
尝试在 proc add
上使用 in
意图而不是 ref
意图:
class Class2 {
var y : int;
}
class Class3 : Class2 {
var z : int;
}
class Class1 {
var count : int;
var x : [0..10] owned Class2?;
proc add(in a : Class2) {
x[count] = a;
count += 1;
}
}
var C1 = new owned Class1();
var C2 = new owned Class2();
var C3 = new owned Class3();
C1.add(C2); // OK
C1.add(C3); // OK!
为什么这很重要?将对子 class (Class3) 的引用传递给期望对父 class (Class2) 的引用的参数不是类型安全的。特别是您可以想象将 class 指针更改为 Class2 而不是 Class3 的方法,这可能会导致调用站点出现其他错误。
我的猜测是 add
函数使用 ref
意图只是为了实现从 C3
的所有权转移。 in
intent 是一种更好的方法,它支持传递子类型(因为上述类型错误情况是不可能发生的)。