Ошибка при приведении ссылочного параметра с dynamic_cast в C ++ - PullRequest
0 голосов
/ 06 ноября 2018

Я изучаю книгу «Гибкая разработка программного обеспечения» Роберта К. Мартина. В примере с принципом открытого-закрытого доступа у меня была проблема с dynamic_cast <>.

пример выглядит следующим образом:

#include <iostream>
#include <vector>
#include<algorithm>

using namespace std;

class Shape {
public:
    virtual void Drow() const = 0;
    virtual bool Precedes(const Shape & s) const = 0;

    bool operator<(const Shape &s){ return Precedes(s);};
};

template<typename T>
class Lessp {
public:
    bool operator()(const T i , const T j) {return (*i) < (*j);}
};


void DrowAllShape(vector<Shape*> &vect){

    vector<Shape*> list = vect;

    sort(list.begin(),
        list.end(),
        Lessp<Shape*>());

    vector<Shape*>::const_iterator i;

    for(i = list.begin(); i != list.end()  ;i++){
        (*i)->Drow();
    }
}

class Square : public Shape{
    public :
        virtual void Drow() const{};
        virtual bool Precedes(const Shape& s) const;
};

class Circle : public Shape{
    public :
    virtual void Drow() const{};
    virtual bool Precedes(const Shape& s) const;
};

bool Circle::Precedes(const Shape& s) const {
    if (dynamic_cast<Square*>(s)) // ERROR : 'const Shape' is not a pointer
        return true;
    else
        return false;

}

и я получаю ошибку в методе Precedes of Circle в чем проблема ??

1 Ответ

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

Вы можете использовать dynamic_cast для:

  1. приведение указателя к другому указателю (также должно быть const - также правильно).
  2. приведение ссылки на другую ссылку (также должно быть const - также правильно).

Вы не можете использовать его для:

  1. приведите указатель на ссылку, или
  2. приведение ссылки на указатель.

По этой причине

dynamic_cast<Square*>(s)

неправильно.

Вы можете использовать

if ( dynamic_cast<Square const*>(&s) ) 

для устранения ошибки компилятора.

Вы можете использовать dynamic_cast<Square const&>(s) (приведение ссылки), но для этого требуется блок try / catch.

try 
{
    auto x = dynamic_cast<Square const&>(s);
}
catch ( std::bad_cast )
{
    return false;
}

// No exception thrown.
return true;
...