оператор приведения к базовому классу в производном классе тонкой оболочки - PullRequest
1 голос
/ 21 мая 2010

У меня есть производный класс, который является очень тонкой оболочкой для базового класса. По сути, у меня есть класс, который можно сравнивать двумя способами в зависимости от того, как вы его интерпретируете, поэтому я создал новый класс, производный от базового класса и имеющий только новые конструкторы (которые просто делегируются базовому классу) и новый operator==. Я хотел бы перегрузить operator Base&() в классе Derived, поэтому в тех случаях, когда мне нужно интерпретировать его как Base.

Например:

class Base
{
  Base(stuff);
  Base(const Base& that);
  bool operator==(Base& rhs); //typical equality test
};

class Derived : public Base
{
  Derived(stuff) : Base(stuff) {};
  Derived(const Base& that) : Base(that) {};
  Derived(const Derived& that) : Base(that) {};
  bool operator==(Derived& rhs); //special case equality test
  operator Base&()
  {
    return (Base&)*this;  //Is this OK?  It seems wrong to me.
  }
};

Если вы хотите простой пример того, что я пытаюсь сделать, представьте, что у меня есть класс String, а String==String - это типичное символьное сравнение. Но я создал новый класс CaseInsensitiveString, который сравнивал без учета регистра на CaseInsensitiveString==CaseInsensitiveString, но во всех остальных случаях вел себя как String. у него даже нет новых элементов данных, только перегруженный operator==. (Пожалуйста, не говорите мне использовать std :: string, это всего лишь пример!)

Я пойду об этом, верно? Что-то кажется подозрительным, но я не могу указать на это пальцем.

Ответы [ 2 ]

2 голосов
/ 21 мая 2010

Поскольку вы используете публичное наследование, C ++ автоматически выполнит преобразование, которое вы пытаетесь реализовать. Там нет необходимости делать это самостоятельно.

Однако я не думаю, что это обязательно хорошее использование наследования. Вы просто используете его здесь без каких-либо виртуальных функций и просто для эффективного создания дочернего класса. В общем случае извлекайте классы для изменения поведения, а не для его повторного использования.

Лучше, я думаю, было бы просто создать внешний алгоритм. Из-за отсутствия виртуальных функций вы все равно не можете заменить базовым указателем / ссылкой, поэтому вместо преобразования в производный класс для принудительного явного сравнения просто вызовите (возможно, друга) автономный метод для сравнения без учета регистра. Вы даже можете обойти алгоритм (используя функтор), если вам нужно динамически изменить его во время выполнения.

2 голосов
/ 21 мая 2010

Поскольку ваш Derived является производным от Base публично, ваш Derived уже может быть конвертирован в Base &. Нет необходимости реализовывать что-либо дополнительное.

Более того, когда речь идет о самом операторе преобразования, вопрос о том, правильно ли вы это делаете или нет, является спорным вопросом, поскольку ваш оператор преобразования никогда не будет использоваться в любом случае. Преобразование производного в базовое всегда выполняется встроенными средствами. Если вы предоставите свой собственный оператор для преобразования (как вы делаете выше), он все равно будет проигнорирован.

Я не понимаю, как вы планируете использовать, если решить исходную проблему с различными подходами сравнения.

...