【问题标题】:using reinterpret_cast for member function arguments对成员函数参数使用 reinterpret_cast
【发布时间】:2011-11-25 13:11:12
【问题描述】:

这里有一些代码:

class containerA
{};

class containerB
: public containerA
{
    public: 
        containerB () {};

        containerB(const containerB& cb)
        {
            cout << "containerB copy ctor" << endl;
        }
};

class containerC
: public containerA
{
    public:
        containerC () {};

        containerC(const containerC& cc)
        {
            cout << "containerC copy ctor" << endl;
        }
};

class myType 
{
    public:

        void someFunction(const containerB& cB) 
        {
            cout << "someFunction(containerB)" << endl;
        }
};

如果假设上面的定义不能改变,通过什么机制可以调用myType的“someFunction”方法,参数类型为“const containerC&”?

我所能找到的只是公开从 myType 派生一个新类型并使用 reinterpret_cast 重新定义“someFunction”,如下所示:

class myTypeNew
: public myType
{
    public:
        void someFunction(const containerC& cC)
        {
            cout << "someFunction(containerC)" << endl;

            const containerB& cbRef = reinterpret_cast<const containerB&>(cC);

            myType::someFunction(cbRef);
        }
};

这样安全吗?我的猜测是,这将取决于 containerB 和 containerC 的运营商如何在 someFunction 中使用它们。

所有容器都是模板化的,但这没有区别,这是一个继承层次结构问题。

非常重要:由于为 containerB 和 containerC 定义了显式类型转换,将 containerA 作为参数,我可以将 containerC 作为直接参数传递给 myType::someFunction,但在这种情况下,会发生复制构造,这正是我想要避免的。

一些具体说明:

  • containerB和containerC的属性完全一样
  • someFunction 仅使用 operator[] 来访问容器元素,并且
  • operator+=(但这是在模板元素级别定义的)

containerB 和containerC 不是两种通用的不同类型:containerC 只是增加了一些成员函数,没有改变对象的内部数据。

【问题讨论】:

    标签: c++ reinterpret-cast


    【解决方案1】:

    不,它不安全,我认为它在未定义行为的范围内。

    类 containerB 和 containerC 完全是两种不同的类型(除了它们都继承自 containerA)。

    因此,为 containerB 和 containerC 调用 someFunction() 的唯一“合法”方法是

    • 提供覆盖类型的 someFunction 的重载
    • 在基类 containerA 中提供 someFunction(containerA& ca) 以及足够的接口

    【讨论】:

    • 我想到了过载,但是有没有一种安全的方法来使用已经定义的 someFunction(containerB) 代码?
    • 如果 containerC 和 containerB 有共同的功能,这应该由 containerA 中的一个实现来表达(B 和 C 继承自它),然后可以被一个接受 containerA& 的 someFunction 覆盖。如果没有通用功能,则必须有两种不同的实现。其他都不好。
    【解决方案2】:

    这根本不安全。

    someFunction 可能会调用属于ContainerB 一部分的方法(否则,它可能将ContainerA 作为其参数类型)。

    如果在不是ContainerB 的对象上调用该方法(因为它是ContainerC,您只是对其进行了类型转换),可能会发生不好的事情(例如,尝试访问不存在的成员变量)。

    【讨论】:

    • 容器B和容器C没有不同的成员变量,someFunction调用operator[]对元素进行算术运算(不依赖于本题)
    • 有没有办法在不重写代码的情况下从 someFunction(containerB) 获取功能?两个容器的代码完全相同。
    【解决方案3】:

    一般来说并不安全

    • containerB 是一个 containerA
    • containerC 是一个 containerA

    由于公共继承的定义,但是

    • containerB 不是 containerC!

    所以你不能只从一种类型转换为另一种类型。

    也许可以考虑编写一个函数FromCtoB(...),它将所需元素从给定的containerC 复制到新的containerB
    请注意,只有在相关数据未声明 private

    的情况下才有可能

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多