Как реализовать кастинг на личный базовый класс в C ++

StackOverflow https://stackoverflow.com/questions/3738556

  •  03-10-2019
  •  | 
  •  

Вопрос

Как реализовать кастинг на личный базовый класс в C ++? Я не хочу использовать такие хаки, как добавление друга и т. Д. Определение оператора общественного кастинга не работает.

РЕДАКТИРОВАТЬ :

Например, у меня есть:

class A {
//base class
}

class AX : private A {
//a child
}

class AY : private A {
//another specialized child
}

class B {
//base class
void do (A a) {//do
    }
}

class BX : private B {
//a child
void do (AX a) {
     B::do( static_cast <A> (a) );
    }
}

class BY : private B {
//another specialized child
void do (AY a) {
    B::do( static_cast <A> (a) );
    }
}

Редактировать2.

Почему я это делаю?

Предположим, я должен определить некоторое свойство, которое довольно тяжело тяжело и может быть несколько похожих типов (например, Velocityx Velocityy и т. Д.). Тогда я хочу иметь возможность иметь занятия, которые могут иметь любой набор этих свойств. Если я хочу обработать эти свойства, очевидно, что я бы предпочел отбросить их на их базовый тип, чем добавить реализацию для каждого изменения. Я не пользуюсь публичным наследством, потому что лучше четко отличить, где это необходимо, чтобы иметь частный интерфейс неявно видимым. Не настоящая проблема, но я хотел бы иметь решение :)

Это было полезно?

Решение

Если определение оператора общественного литья не работает, вы можете попробовать с регулярной функцией:

class D: private B {
    public:
        B& asB() { return static_cast<B&>(*this); }
};
...
D d;
d.asB().methodInB();
...

Во всяком случае, какой смысл? Если D происходит в частном порядке от B, тогда вы не должны использовать D как B снаружи.

Другие советы

Вы можете просто использовать аккумулятор в стиле C. Нет необходимости в каких-либо «хаках» или «реализациях». Упаковка в явную функцию служит «Chasts Chates Cleans - плохие» люди

template<typename Targ, typename Src>
typename boost::enable_if<boost::is_base_of<Targ, Src>, Targ>::type &
private_cast(Src &src) { return (Targ&)src; }

Иметь в безопасности, вам нужно убедиться, что Targ на самом деле является частной или общественной базой. Это делается boost::is_base_of.


Конечно, вы должны предпочесть функции участников в соответствующем полученном классе, который возвращает базовый указатель вместо того, чтобы делать такое актеры..


Определение оператора общественного кастинга не работает.

Это не имеет смысла для меня ... зачем вообще делать базовый класс? Просто сделайте его общественностью. Причина, по которой ваши функции преобразования не работают, заключается в том, что стандарт требует, чтобы неявные преобразования никогда не рассматривают функции преобразования в базовый класс, сам класс или void.

У меня есть случай для этого; Я унаследовал из большого и волатильного базового класса, который все время добавляет функции и почти никогда не является функцией базового класса, которая будет работать правильно в моем подклассе, поэтому я наследую в частном порядке.

Я думаю, что это простым, чтобы сделать функцию, которая возвращает базовый класс. Ниже я перечислю полностью исправленную программу; Пожалуйста, попробуйте собрать свой код перед отправкой вопроса, поскольку использование идентификаторов, таких как «DO», как имен функций, скорее всего, сделают каждый компилятор несчастной .. :-( :-(

class A {
  //base class                                                                                                                                                          
};

class AX : private A {
  //a child                                                                                                                                                             
 public:
  A *ToA() { return this; }
};

class AY : private A {
  //another specialized child                                                                                                                                           
 public:
  A *ToA() { return this; }
};

class B {
  //base class                                                                                                                                                          
 protected:
  void do_it (A a) {};
};

class BX : private B {
  //a child                                                                                                                                                             
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

class BY : private B {
  //another specialized child                                                                                                                                           
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top