2

这是一些代码:

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 只是添加了一些成员函数,对象的内部数据没有改变。

4

3 回答 3

2

这根本不安全。

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

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

于 2011-11-25T13:19:16.000 回答
2

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

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

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

  • 提供覆盖类型的 someFunction 的重载
  • 在基类 containerA 中提供 someFunction(containerA& ca) 以及足够的接口
于 2011-11-25T13:20:25.763 回答
1

它通常是不安全的

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

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

  • containerB 不是一个containerC

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

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

于 2011-11-25T13:21:47.833 回答