C++ - 从抽象对象创建非抽象对象

C++ - Creating non-abstract objects from abstract objects

本文关键字:对象 抽象 创建 C++      更新时间:2023-10-16

我有这个基类

class Object {
 ...
 public:
  virtual void move() = 0;
  virtual void move(string) = 0;
  virtual void powerOn() = 0;
  virtual void powerOff() = 0;
  virtual void speak() = 0; 
};

这将是不同类的基类

class Electronics : public Object {
 ...
 public:
  virtual void powerOn();
  virtual void powerOff();
};
void Electronics::powerOn() { ... }
void Electronics::powerOff() { ... }
class Phone : public Electronics {
 ...
 public:
};

现在,如果我想创建一个对象 Phone,它使用 powerOn(( 和 powerOff(( 方法。我不需要其他三种方法。

Object *obj = new Phone;

但这可能会给我一个错误说

undefined reference to move()
undefined reference to move(string)
undefined reference to speak()

我的问题是,如何避免此错误。Phone不需要这些功能,但它需要我用它们做一些事情。如何克服此错误?

谢谢

您可以在ElectronicsObject中提供这些虚拟方法的空实现(使方法非抽象(。或者,如果两者都需要这样,则需要在 Phone 中重新实现它们。但是,您不能将它们"隐藏"在Phone中,除非您将它们从其底座中删除。

如前所述,您可以在 Electronics 类中创建它们的空实现,换句话说,覆盖此类中的方法,并简单地让它有一个空的主体。(请参阅此处的示例:http://ideone.com/jM2hX7(

#include <iostream>
using namespace std;
class Object {
 public:
  virtual void move() = 0;
  virtual void move(string) = 0;
  virtual void powerOn() = 0;
  virtual void powerOff() = 0;
  virtual void speak() = 0; 
};
class Electronics : public Object {
 public:
  virtual void move() override {}
  virtual void move(string) override {}
  virtual void powerOn() override {cout << "powerOn" << endl;}
  virtual void powerOff() override {cout << "powerOff" << endl;}
  virtual void speak() override {} 
};
class Phone : public Electronics {
  virtual void powerOn() override {cout << "phone:powerOn" << endl;}
  virtual void powerOff() override {cout << "phone:powerOff" << endl;}
};
int main() {
    Object* phone = new Phone;
    phone->move();
    phone->powerOn();
    phone->powerOff();
    phone->speak();     
    delete phone;
    return 0;
}

输出:

phone:powerOn
phone:powerOff

更重要的是,虽然你可能想重新考虑你的类设计,但真的有必要拥有纯虚拟方法,如powerOnpowerOffspeak、......在你的班级里:Object.对象听起来很通用,这些功能听起来更具体。 理想情况下,Object应该只包含对从它继承的所有类有意义的函数。

这些函数在Electronics类中可能更有意义,即使这样,似乎也有点太笼统了。

如果确实需要在Object类中包含这些对象,那么我个人会将其重命名为更多的说法。