typeid.name () не изменяется при итерации по вектору.Динамическое приведение и указание указателя на базовый класс - PullRequest
0 голосов
/ 29 ноября 2018

Ответ: Короче используйте виртуальные функции!Так что на самом деле не используйте это как хороший дизайн, но в учебных целях читайте!

Я хочу начать с того, что я использую c ++ и Qt, у меня есть вектор указателей Shape (базовый класс)

Редактировать: doSomething () не является членом базового класса, а является членом производного класса.Вот почему я использую dynamic_cast для передачи Shape * в Derived *, чтобы я мог получить к нему доступ.Я действительно делаю это просто из любопытства, хотя и для других людей, узнающих о системе типов c ++

    #include <vector>
    using namespace std;
    vector<Shape *> vec;

Где я отталкиваю некоторые производные классы формы

    vec.push_back(new Square());
    vec.push_back(new Circle());

Okзатем я получаю итератор к началу

    vector<Shape *>::iterator tmp = vec.begin();

Здесь я хочу перебрать векторы

    for(;tmp != vec.end(); ++tmp)
    {
        if(typeid(**tmp).name() == typeid(Square).name())
        {
            Square * sptr = dynamic_cast<Square *>(*tmp);
            sptr->doSomething();
        }
        else if(typeid(**tmp).name() == typeid(Circle).name())
        {
            Circle * cptr = dynamic_cast<Circle *>(*tmp);
            cptr->doSomething();
        }
    }

Однако оба результата приводят к выводу Square;не круг для второго.Я попытался сравнить ячейки памяти typeid

Примерно так:

    &typeid(**tmp) == &typeid(Square)

и то же самое для круга, но tmp всегда приводит к квадрату для случая выше и когда запускается против круга сразу после этого... Динамическое приведение делает что-то с вектором в целом или я что-то упускаю из-за того, как работает typeid ()?

Редактировать: вот ответ, спасибо user4581301 (я тоже добавил кое-что!):

#include <iostream>
#include <vector>
#include <typeinfo>

struct Shape
{
    virtual ~Shape(){} //Something here must be virtual or pure virtual!
};

struct Circle: Shape
{
    void doSomething(){std::cout << "Circle" << std::endl;}
};
struct Square: Shape
{
    void doSomething(){std::cout << "Square" << std::endl;}
};

int main()
{
    std::vector<Shape *> vec;
    vec.push_back(new Square());
    vec.push_back(new Circle());
    std::vector<Shape *>::iterator tmp = vec.begin();

        for(;tmp != vec.end(); ++tmp)
        {
            if(&typeid(**tmp) == &typeid(Square))
            {
                Square * sptr = dynamic_cast<Square *>(*tmp);
                sptr->doSomething();
            }
            else if(&typeid(**tmp) == &typeid(Circle))
            {
                Circle * cptr = dynamic_cast<Circle *>(*tmp);
                cptr->doSomething();
            }
        }


}

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

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

0 голосов
/ 29 ноября 2018

Работает, как предполагалось, с doSomething в качестве функции virtual.Если это не virtual, то сама компиляция завершится неудачно (если в классе Shape нет других функций, которые virtual).Динамическое приведение не будет выполнено, если тип источника не является полиморфным.

Если это virtual, вам не нужно делать то, что вы делаете, чтобы определить тип.Пусть полиморфизм сделает свое волшебство.Вы можете сократить свой код следующим образом:

#include <iostream>
#include <vector>

class Shape { public: virtual void doSomething() {std::cout << "In Shape\n";}};
class Circle: public Shape {public: void doSomething() {std::cout << "In Circle\n";}};
class Square: public Shape {public: void doSomething() {std::cout << "In Square\n";}};

int main() {
    std::vector<Shape *> vec;
    vec.push_back(new Square);
    vec.push_back(new Circle);

    for(auto tmp = vec.begin();tmp != vec.end(); ++tmp)
    {       
        (*tmp)->doSomething();        
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...