使用reinterpret_cast作为成员函数参数

时间:2011-11-25 13:11:13

标签: c++ reinterpret-cast

这里有一些代码:

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;
        }
};

如果你认为上面的定义不能改变,可以通过什么机制来调用&#34; someFunction&#34; myType的方法,类型为&#34; const containerC&amp;&#34;?

我所能找到的只是从myType公开派生一个新类型并重新定义&#34; someFunction&#34;使用reinterpret_cast如下:

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仅使用opearator []来访问容器元素,
  • operator + =(但这是在模板元素级别定义的)

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

3 个答案:

答案 0 :(得分:2)

根本不安全。

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

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

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:1)

通常不安全

  • containerB containerA
  • containerC containerA

由于公共继承的定义,但

  • containerB 不是 containerC

因此您无法从一种类型转换为另一种类型。

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

的情况下,才可能这样做