вот код:
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;
}
};
Если вы предполагаете, что приведенное выше определение не может быть изменено, с помощью каких механизмов можно было бы вызвать метод «someFunction» myType с аргументом типа «const containerC&»?
Все, что я смог найти, это публично вывести новый тип из myType и переопределить «someFunction» с помощью 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 использует только оператор [] для доступа к элементам контейнера и
- оператор+= (но это определяется на уровне элемента шаблона)
containerB и containerC не являются двумя разными типами: containerC имеет только некоторые добавленные функции-члены, никакие внутренние данные объекта не изменяются.