C++抽象类参数错误解决方法

C++ abstract class parameter error workaround

本文关键字:解决 方法 错误 参数 抽象类 C++      更新时间:2023-10-16

下面的代码片段产生一个错误:

#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* x = new B() ; test(x);)传递任何扩展/实现基类A的类作为参数

干杯

由于无法实例化抽象类,因此按值传递几乎肯定是一个错误;您需要通过指针或引用传递它:

void test(A& x) ...

void test(A* x) ...

传递值将导致对象切片,几乎可以保证会产生意外(以糟糕的方式)后果,因此编译器将其标记为错误。

当然,更改签名:

void test(A& x)
//or
void test(const A& x)
//or
void test(A* x)

您的版本不起作用的原因是A类型的对象在逻辑上没有意义。它很抽象。传递引用或指针会绕过这一点,因为作为参数传递的实际类型不是A,而是A的实现类(派生的具体类)。

要绝对清楚,问题是,无论何时定义类:

#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传递以防止复制。