在Chapel中接受派生类的Class方法

问题描述 投票:2回答:1

考虑以下代码,我希望将一个类(此处为Class2)及其派生类(此处为Class3)的实例存储在另一个类(此处为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
derived-class chapel
1个回答
1
投票

尝试使用in意图代替ref上的proc add意图:

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!

为什么这很重要?将对子类(Class3)的引用传递给期望对父类(Class2)进行引用的参数是不安全的。特别是,您可以想象将类指针更改为Class2而不是Class3的方法,这可能会导致调用站点出现其他错误。

我的猜测是,add函数使用ref意图只是为了从C3进行所有权转移。 in意图是一种更好的方法,它支持传递子类型(因为上述类型错误情况是不可能的)。

© www.soinside.com 2019 - 2024. All rights reserved.