首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >纯虚函数的C++继承

纯虚函数的C++继承
EN

Stack Overflow用户
提问于 2011-05-15 04:09:32
回答 5查看 9.9K关注 0票数 4

我正在尝试创建一个类作为基对象,然后将其子类化(=实现)以服务于各种目的。

我想定义一个或多个纯虚函数,这样无论基类是什么子类,都是必需的,并且不会忘记实现它们。

有一点需要注意,纯虚函数的签名包括基对象的类型。一旦划分了子类,函数定义当然就不再与基类定义相匹配。例如:

代码语言:javascript
复制
class BaseItem 
{
public:
    virtual std::string getDifferences(const BaseItem& item) = 0;
}

所以,在派生类中,我想做的是:

代码语言:javascript
复制
class DerivedClass : public BaseItem
{
public:
    virtual std::string getDifferences(const DerivedClass& item) = 0;
private:
    std::string derivedItemCustomObject;
}

编译器当然不会接受。当然,我可以将其设置为BaseItem,但这样我就不能利用派生类中的任何对象。

我必须使用强制转换来完成此操作吗?

如果我的意图/问题不清楚,请告诉我。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-05-15 12:50:57

无需更改函数签名即可实现。请看以下内容:

代码语言:javascript
复制
class BaseItem 
{public:
    virtual std::string getDifferences(const BaseItem& item) = 0;
};

class DerivedClass : public BaseItem
{public:
    virtual std::string getDifferences(const BaseItem& item)  // keep it as it's
    {
       const DerivedClass& derivedItem = static_cast<const DerivedClass&>(item);
    }
};

可以毫无畏惧地使用static_cast<>,因为DerivedClass::getDifferences()只为DerivedClass对象调用。为了说明,

代码语言:javascript
复制
BaseItem *p = new DerivedClass;
DerivedClass obj;
p->getDifferences(obj);  // this always invoke DerivedClass::getDifferences

如果您担心有时可能会将任何其他派生类对象作为参数传递给该方法,那么请改用dynamic_cast<>,并在转换失败时抛出exception。

票数 4
EN

Stack Overflow用户

发布于 2011-05-15 04:24:03

现在还不清楚你想要实现什么。假设编译器允许您这样做(或者您是通过强制转换的方式做到这一点),那么它将在类型系统中打开以下漏洞:

代码语言:javascript
复制
class BaseItem 
{
public:
    virtual std::string getDifferences(const BaseItem& item) = 0;
};

class DerivedClass : public BaseItem
{
public:
    virtual std::string getDifferences(const DerivedClass& item) 
    {
        item.f(); 
        // ... 
    }

    void f() const {}
};

class DerivedClass2 : public BaseItem
{
public:
    virtual std::string getDifferences(const DerivedClass2& item) { ... }
};

void g()
{
    BaseItem* x = new DerivedClass;

    // oops, calls DerivedClass::f on an instance of DerivedClass2
    x->getDifferences(DerivedClass2());
}

您的设计可能是错误的。

票数 2
EN

Stack Overflow用户

发布于 2011-05-15 04:30:16

我假设编译器接受,但是DerivedClass::getDifferences没有覆盖BaseItem::getDifferences。下面是一种实现你明显想要的东西的方法

代码语言:javascript
复制
template <typename T>
class DerivedHelper: public BaseItem {
public:
   virtual std::string getDifferences(const BaseItem& item) {
      getDifferences(dynamic_cast<const T&>(item));
   }
   virtual std::string getDifferences(const T& item) = 0;
}; 

class DerivedClass : public DerivedHelper<DerivedClass>
{
public:
   // not more needed but providing it will hide getDifferences(const BaseItem& item)
   // helping to statically catch some cases where a bad argument type is used.
   virtual std::string getDifferences(const DerivedClass& item) = 0;
private:
   std::string derivedItemCustomObject;
};

但请注意,如果参数不是正确的类,运行时检查将抛出异常。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6004501

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档