如何使用抽象类?
我正在尝试将一个抽象类作为函数的返回类型。
gcc的说法是 "invalid abstract return type for member function",并附带以下解释:
当一个抽象类中的函数被声明为返回该抽象类的实例时,这是不被允许的。
现在,我理解这句话的意思,但我不理解在下面这种情况为何无效:
SlipCell operator+(const SlipCell& X) {
return ((SlipOp*)*getOperator())->add(*this, X);
}
在这个例子中,return 返回一个具体对象,该对象继承自 SlipCell,SlipCell 是一个抽象类。我原本以为,对未使用纯虚函数(PVF)的 SlipCell 对象的引用会直接以已定义的函数工作;对PVF的引用会通过虚表解析到具体对象中的实现。错误信息似乎表示这是一种错误的理解,必须返回一个具体对象。有没有办法绕过这个?
建议的做法是使用引用或指针。这在这里并不适用,因为返回的对象是临时的,因此把它们放在栈上似乎是个好主意,而指向栈上对象的指针可能不太好用(我需要再考虑,因为它也有可能可行)。
为了把这个问题放在一个框架里,我正在实现一个算术运算,使用一个包含异构对象集合的类。如果我执行 a + b,且不提供额外信息,那么运算的结果在放到栈上时,一旦超出作用域就会消失。很好,当我处理具体对象时,它确实可用。
由于完全在我可控的条件下,我决定把执行算术运算的函数移到基类,并返回一个基类对象。基类就是引发问题的那个抽象类。
另一个潜在的特性是效率。算术函数被分离到另一个虚拟类结构中。每个具体类在这组为每种数据类型设置的其他继承结构中有一个指向具体对象的指针。这样就可以通过引用这条“另一条继承链”中的具体对象实例来进行算术运算,它会为我完成运算。
我一直尝试把所有操作控制在单行程序中,避免函数调用的开销。直到我把算术函数移动到抽象类为止,这一切都还能成立。
cygwin
(GCC) 16.0.1使用 -std=c++20
解决方案
抽象类的类型只能用于引用和指针。原因在于如果你要使用一个实际对象,那就需要为它分配内存!这在你定义本地对象、全局对象、自由存储区中的对象(如堆)、无论是按值传参还是像你这种情况从函数返回按值时,都是成立的。
在每种情况下,编译器都必须知道要为对象提供多少存储,而对于抽象类来说,这一信息是未知的。