下面的代码段会产生错误:
#include <iostream>
using namespace std;
class A
{
public:
virtual void print() = 0;
};
void test(A x) // ERROR: Abstract class cannot be a parameter type
{
cout << "Hello" << endl;
}
是否存在此错误的解决方案/解决方法/替换
更好/更好virtual void print() = 0;
带
virtual void print() = { }
编辑:我希望能够通过使用多态来传递任何扩展/实现基类A作为参数的类(即A* x = new B() ; test(x);
)
干杯
答案 0 :(得分:23)
由于无法实例化抽象类,因此按值传递几乎肯定是一个错误;你需要通过指针或引用传递它:
void test(A& x) ...
或
void test(A* x) ...
按值传递将导致object slicing,几乎可以保证产生意外(以坏的方式)后果,因此编译器会将其标记为错误。
答案 1 :(得分:4)
当然,更改签名:
void test(A& x)
//or
void test(const A& x)
//or
void test(A* x)
您的版本不起作用的原因是因为A
类型的对象在逻辑上没有意义。这是抽象的。传递引用或指针是因为作为参数传递的实际类型不是A
,而是实现类A
(派生的具体类)。
答案 2 :(得分:0)
绝对要清楚,问题是,每当定义一个类时:
#include <iostream>
class foo {
public:
char *name = (char *)"foo";
};
并将该类的实例传递给函数,它将创建一个副本:
void bar(foo a) {
a.name = (char *)"bar";
}
int main() {
foo x;
bar(x);
std::cout << x.name << std::endl; // foo
return 0;
}
关于继承,它创建一个副本作为基类的实例:
#include <iostream>
class foo {
public:
char *name = (char *)"foo";
};
class bar: public foo {
public:
char *name = (char *)"bar";
};
void baz(foo a) {
std::cout << a.name << std::endl;
}
int main() {
bar x;
baz(x); // again, foo
return 0;
}
所以,这样做
void baz(AbstractType a) {
...
}
您要告诉编译器复制AbstractType
作为AbstractType
本身的实例,这是非法的。
将其作为const AbstractType &a
传递以防止复制。