Search code examples
c++reinterpret-cast

using reinterpret_cast for member function arguments


here's some code:

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

If you assume that the above definition cannot be changed, through what mechanisms would it be possible to call the "someFunction" method of myType with the argument of type "const containerC&"?

All I could find was to publicly derive a new type from myType and redefine the "someFunction" using reinterpret_cast as follows:

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

Is this safe? My guess is that it will depend on the operators of containerB and containerC with respect to how they are used in someFunction.

All containers are templated, but this makes no difference, it's an inheritance hierarchy problem.

Very Important: Since the explicit type conversion is defined for containerB and containerC taking the containerA as an argument, I could pass the the containerC as a direct argument to myType::someFunction, but in this case, copy construction takes place, and that is exactly what I want to avoid.

Some specific notes:

  • attributes of both containerB and containerC are exactly the same
  • someFunction utilises only opearator[] for accessing the container elements, and
  • operator+= (but this is defined on the template element level)

containerB and containerC are not two general different types: containerC has just some added member functions, no internal data of the object is changed.


Solution

  • No it is not safe and I would assume it's within the realm of undefined behavior.

    The classes containerB and containerC are two different types altogether (with the exception that they both inherit from containerA).

    So the only "legal" ways to call someFunction() for containerB and containerC would be

    • Provide an overload of someFunction covering the types
    • Provide a someFunction(containerA& ca) together with a sufficient interface within base class containerA