что такое полиморфный тип в C++?

Я нашел в одной статье, говоря "static_cast, используется для неполиморфного преобразования типа, и dynamic_cast используется для полиморфного преобразования типа". Я понимаю, что интервал и дважды не является полиморфными типами.

Однако я также нашел, что static_cast может использоваться между базовым классом и производным классом. Что здесь означает полиморфный тип? Некоторые люди говорят, что полиморфный тип означает базовый класс с виртуальной функцией. Это правильно? Действительно ли это - единственная ситуация? Что еще? Может кто-либо мог разработать это для меня больше?

26
задан skydoor 9 January 2010 в 04:39
поделиться

4 ответа

Прежде всего, статья не совсем правильная. Dynamic_Cast проверяет тип объекта и может потерпеть неудачу, Static_cast не проверяет и в значительной степени требует, чтобы программитор знал, что они делают (хотя это вызовет ошибки компиляции для некоторых вопиющих ошибок ), но они могут как использоваться в полиморфных ситуациях . ( Dynamic_Cast имеет дополнительное требование, чтобы по крайней мере один из участвующих типов имеет виртуальный метод.)

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

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

Пример полиморфизма:

struct Animal {
  virtual ~Animal() {}
  virtual void speak() = 0;
};

struct Cat : Animal {
  virtual void speak() { std::cout << "meow\n"; }
};

struct Dog : Animal {
  virtual void speak() { std::cout << "wouf\n"; }
};

struct Programmer : Animal {
  virtual void speak() {
    std::clog << "I refuse to participate in this trite example.\n";
  }
};

Тренировки вышеуказанных классов - также см. Мой Общий фабричный пример :

std::auto_ptr<Animal> new_animal(std::string const& name) {
  if (name == "cat") return std::auto_ptr<Animal>(new Cat());
  if (name == "dog") return std::auto_ptr<Animal>(new Dog());
  if (name == "human") return std::auto_ptr<Animal>(new Programmer());
  throw std::logic_error("unknown animal type");
}

int main(int argc, char** argv) try {
  std::auto_ptr<Animal> p = new_animal(argc > 1 ? argv[1] : "human");
  p->speak();
  return 0;
}
catch (std::exception& e) {
  std::clog << "error: " << e.what() << std::endl;
  return 1;
}

Также возможно использовать полиморфизм без наследства , так как это действительно дизайн техника или стиль . (Я отказываюсь использовать BUZZWord здесь ...: P)

17
ответ дан 28 November 2019 в 07:25
поделиться

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

Итак, это « полиморфный тип».

struct Test {
  virtual ~Test();
};
8
ответ дан 28 November 2019 в 07:25
поделиться

Static_Cast может выполнять преобразования между указателями на соответствующие классы, не только из полученного класса на его базу, но и из базового класса до его получения. Это гарантирует, что, по крайней мере, классы совместимы, если бы правильный объект преобразован, , но никакой проверки безопасности не выполняется во время выполнения , чтобы проверить, является ли преобразованным объектом, на самом деле является полным объектом типа назначения. Поэтому программисту в зависимости от того, чтобы преобразование было безопасным. С другой стороны, накладные расходы на проверку безопасности типа Dynamic_cast можно избежать.

Static_Cast также может использоваться для выполнения любого другого не указателя преобразования, которое также может быть выполнено неявно, как, например, для стандартных преобразований между фундаментальными типами:

double d=3.14159265;
int i = static_cast<int>(d); 

Dynamic_Cast Может использоваться только с указателями и ссылками на объекты. Его целью является обеспечение того, чтобы результат преобразования типа является действительным полным объектом запрошенного класса.

Следовательно, Dynamic_Cast - это всегда успешно , когда мы бросаем класс на один из его базовых классов.

// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;

class CBase { virtual void dummy() {} };
class CDerived: public CBase { int a; };

int main () {
 try {
    CBase * pba = new CDerived;
    CBase * pbb = new CBase;
    CDerived * pd;

    pd = dynamic_cast<CDerived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast" << endl;

    pd = dynamic_cast<CDerived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast" << endl;

    } catch (exception& e) {cout << "Exception: " << e.what();}
    return 0;
 }

Примечание Совместимость : Dynamic_Cast требует информации о времени выполнения (RTTI), чтобы отслеживать динамические типы. Некоторые компиляторы поддерживают эту функцию в качестве опции, который по умолчанию отключен. Это должно быть включено для проверки типа выполнения, используя Dynamic_Cast, чтобы работать правильно.

Виртуальные функции несут ответственность за полиморфизм времени выполнения в C ++. Класс, имеющий хотя бы одну виртуальную функцию, имеет полиморфный тип.

Подробнее ....

Прочитайте это тоже. Было четко написано, что класс, который объявляет или наследует виртуальную функцию, называется полиморфным классом.

14
ответ дан 28 November 2019 в 07:25
поделиться

Я думаю, что полная фраза - это «полиморфный тип , отливка ». Вы правы, что Static_cast работает на типов, которые не связаны от наследования (Double - Int, и т. Д.), а остальные ответы указывают на то, как работают отказ.

Я не думаю, что утверждение подразумевает существование мифического полиморфного типа, хотя - только что Static_Cast также работает на не связанных типах. Заявление было немного запутанным, хотя и хорошо уточнить.

2
ответ дан 28 November 2019 в 07:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: