是否有可能在编译时强制两个派生类对于某个重写函数始终返回不同的值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否有可能在编译时强制两个派生类对于某个重写函数始终返回不同的值?相关的知识,希望对你有一定的参考价值。

在编译时是否可以强制接受以下内容:

class B {
public:
    virtual constexpr const char* getKeyStr() const = 0;
};

class D1 : public B {
public:
    constexpr const char* getKeyStr() const override { return "D1"; }
};

class D2 : public B {
public:
    constexpr const char* getKeyStr() const override { return "D2"; }
};

...但是以下不是吗?我们不希望D1D2返回相同的键字符串:

class B {
public:
    virtual constexpr const char* getKeyStr() const = 0;
};

class D1 : public B {
public:
    constexpr const char* getKeyStr() const override { return "D1"; }
};

class D2 : public B {
public:
    constexpr const char* getKeyStr() const override { return "D1"; } // can we error out here at compile time?
};

说明:

  1. 在此示例中,我仅显示两个派生类,但是我要实现的目标是将此约束发布到任意数量的派生类上。

  2. 要解决的基本问题:我正在考虑一个序列化/反序列化应用程序,其中每个具有相同基类的对象将能够生成自身的文本/字符串表示形式,并将其写入文件,并且在给定该字符串返回(我们称其为内容字符串),将能够重建相应的数据。

    反序列化期间,应用程序代码应该能够从内容字符串的关键部分(将其称为关键字字符串)来判断应该重构哪个派生对象。因此,对于每个派生类,键串都必须是唯一的。我知道type_info::name可能是唯一的,但它不是可自定义的(或与编译器无关?)。

  3. 关于getKeyStr()函数(对应于上述键字符串),对于相同派生类的所有对象,它应始终返回相同的字符串。

答案

是,您可以在编译时检查getKeyStrD1D2返回的“字符串”是否不同。

首先提供在编译时比较2 const char *的函数:

constexpr bool different(const char *x, const char *y)
{
  while(*x != '\0' )
    if (*x++ != *y++) return true;

  return *y != '\0'; 
}

然后比较返回的值:

// this will trigger, if returned strings are the same.
static_assert( different(D1{}.getKeyStr(), D2{}.getKeyStr()) );  

这里是demo

以上是关于是否有可能在编译时强制两个派生类对于某个重写函数始终返回不同的值?的主要内容,如果未能解决你的问题,请参考以下文章

派生类成员函数调用时 error C2248: 无法访问 protected 成员 的排雷之路

函数的重载重写与隐藏

强制基方法调用

多态

为啥当我有两个函数时编译器没有显示错误,一个将基类作为参数,一个将派生类作为参数?

C++多态