2009-08-20 6 views
1

У меня есть следующие пары функций:Определение идентичности объекта из ссылки на суперкласс

void RegisterSink(ISink & Sink) 
void UnregisterSink(ISink & Sink) 

Где ISink это абстрактный базовый класс. Внутри я хотел бы сохранить указатели на раковины в std :: set. Когда раковина незарегистрирована, я просто ищу указатель в своем наборе и удаляю его. Мой вопрос заключается в том, есть ли какой-либо способ, что использование адреса параметра Sink даст разные результаты, хотя один и тот же объект передавался как параметр. Я знаю, что указатели могут измениться при кастинге в некоторых множественных наследованиях szenarios, но как насчет этой ситуации?

Заранее благодарен!

ответ

1

В случае множественного наследования значение «того же объекта» иногда не очевидно. Например, если ISink присутствует дважды в списке базовых классов и не был унаследован с «виртуальным», такая ситуация возможна:

class A {}; 
class B:public A {}; 
class C:public A {}; 
class D:public B,public C {}; 
... 
void f(A *a); 
... 
{ 
    D d; 
    f(static_cast<B*>(&d)); 
    f(static_cast<C*>(&d)); 
} 

В этом случае F получит два разных адреса. Является ли тот же объект или нет, вероятно, зависит от контекста. Если вы хотите рассматривать их как один и тот же объект, dynamic_casting to void * может помочь - он относится к большинству производных классов (конечно, требуется виртуальное в A)

8

Как вы сказали, адреса указателей могут меняться при кастинге между виртуальными классами с множественным наследованием. Однако в вашем случае статический тип всегда один и тот же: ISink, поэтому сравнение двух точек этого статического типа гарантированно будет безопасным и даст воспроизводимые результаты.

2

Смещение корректировки производится в случае множественных наследований. IFAIK, они должны привести к указателям, сравнивающим равные и сортируемые с std :: less <> если только ваш объект наследует несколько раз от ISink, а ISink не является виртуальным базовым классом во всех случаях.

Смежные вопросы