【问题标题】:C++ - Creating non-abstract objects from abstract objectsC++ - 从抽象对象创建非抽象对象
【发布时间】:2016-07-23 04:41:09
【问题描述】:

我有这个基类

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 的这些功能,但它需要我对它们做一些事情。我怎样才能克服这个错误?

谢谢

【问题讨论】:

  • 您可以从 Object 中删除这些函数,并在您真正需要它们的较低子类中使用它们
  • 我需要稍后做类似的事情: Object *phone = new Phone。后来,当我调用 phone->powerOn() 时,它会说 Object 类中没有 powerOn() 方法

标签: c++ inheritance abstract-class pure-virtual


【解决方案1】:

您可以在Electronics 或Object 中提供这些虚拟方法的空实现(使方法非抽象)。或者,如果两者都需要这种方式,您需要在 Phone 中重新实现它们。但是,您不能将它们“隐藏”在 Phone 中,除非您将它们从其基础中移除。

【讨论】:

  • 对不起,“空实现”是什么意思
  • @thisisalongdisplayname 正如 TommyA 所提到的,空实现是具有空主体的函数/方法,例如foo() { }
【解决方案2】:

如前所述,您可以在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

更重要的是,尽管您可能想重新考虑您的类设计,但是否真的有必要在您的类中使用纯虚方法,例如 powerOn、powerOff、speak、...:Object。对象听起来很笼统,而这些功能听起来更具体。 Object 理想情况下应该只包含对所有从它继承的类都有意义的函数。

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

如果确实需要在Object 类中包含这些对象,那么我会亲自将其重命名为更具说明性的名称。

【讨论】:

  • 是的,但是当我这样做时:Object *phone = new Phone,然后在稍后调用 phone>powerOn(),它会说 Object 类没有称为 powerOn() 的方法跨度>
  • @thisisalongdisplayname 如果你已经实现了powerOn 方法,就像在Electronics 类中一样,为什么会这样说?
  • 由于Phone是Object类型,当我调用pwerOn()时,它会在Object类中寻找powerOn()。不对吗?
  • @thisisalongdisplayname 在这种情况下,我肯定会将您的班级名称 Object 更改为与使用它的子班级更相关的名称。我不喜欢给类命名Object,这在类似 Java 的语言中可能是有意义的,因为一切最终都继承自这样的类,但在 C++ 中,我会选择更具体的命名。
  • 很抱歉给您带来了困惑。这不是我的实际代码。我正在做一个学校作业,所以我不能在这里发布实际代码。这只是我的代码中发生的事情的代表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 2016-07-21
  • 2020-09-01
  • 1970-01-01
  • 2012-11-27
相关资源
最近更新 更多