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.

有帮助吗?

解决方案

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

其他提示

It is not safe at all.

someFunction will probably call a method that is part of ContainerB (otherwise, it could have ContainerA as its parameter type).

If that method is called on an object that is not a ContainerB (because it is ContainerC, you just typecasted it), bad things can happen (e.g. trying to access member variables that do not exist).

It is generally not safe as

  • containerB is a containerA
  • containerC is a containerA

due to definition of public inheritance but

  • containerB is not a containerC!

so you cant just cast from one type to another.

Maybe consider writing a function FromCtoB(...) wich copys the needed elements from a given containerC to a new containerB.
Note that this would be possible only in case the relevant data isn't declared private

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top