【问题标题】:Making Base Class Conversion Functions Public with a Protected Inheritance使用受保护的继承公开基类转换函数
【发布时间】:2021-07-22 02:02:03
【问题描述】:

我有一个继承自另一个的类。我不希望此类的用户意外地在子对象上使用基类函数。显而易见的答案是使继承受保护或私有。

但是,我确实希望将子对象隐式转换为基类。此强制转换的默认实现在大多数情况下是隐藏的,因为它被赋予受保护/私有状态,并且尝试定义用户转换会引发警告: "converting ‘B’ to a reference to a base class ‘A’ will never use a type conversion operator [-Wclass-conversion]"

很公平。由于这条路对我关闭,我必须转过来问:有没有办法将默认类型转换重新分类到公共空间,以便隐式转换可以继续存在?

作为我正在努力工作的一个例子:

class A
{
public:
    A()
    {
        
    }
    A(A& otherA)
    {
        
    }
};

class B : protected A
{
public:
    operator A& ()
    {
        return *this;
    }
    
};

int main() {
    B guy;
    A otherguy(guy);
}

遗憾的是,我不能只将基类中的违规函数声明为受保护:如果用户显式转换为该基类,我希望它们可用。在我的特殊情况下,B 不包含任何数据,只是 A 周围的便利/安全包装,因此我无需担心通过允许此转换来切片或以其他方式丢失任何信息。我只是不希望用户将后端 API(目前通过公共继承公开)误认为是对用户更友好的包装 API 的一部分。

【问题讨论】:

  • 如果目标是让用户确认他们正在转换,您是否考虑过只使用一个显式函数,例如B.convert_to_a?必须写 guy.convert_to_a() 清楚地表明我理解转换的后果。
  • 我有一个这样的函数,它提供了我希望他们进入后端 API 的显式转换。但是,我不想重写当前隐式转换性质的 B 的每次使用来调用该显式函数。许多请求 A 的函数目前在我的代码库中接受 B。我也不想规范化调用显式转换,因为在每种情况下都需要它。

标签: c++ c++11


【解决方案1】:

我不认为你可以按照你要求的方式做你想做的事

我会使用封装而不是继承:

class A {
public:
    T func1(); // should be visible via B
    void func2(); // should not be visible via B
};

class B { // note: not inheriting from A
    A base; // B explicitly defines its "base class sub-object"
public:
    // provide access to base class sub-object
    operator A&() { return base; }

    // provide access to func1
    T func1() { return base.func1(); }
};

void use(A &a) { a.func2(); }

int main() { 
    B b;

    b.func1(); // no problem
    // b.func2(); // won't work;

    use(b);    // no problem. Uses our conversion operator
}

【讨论】:

    猜你喜欢
    • 2019-08-24
    • 2020-09-17
    • 2018-08-23
    • 1970-01-01
    • 2012-08-19
    • 2010-10-26
    相关资源
    最近更新 更多