Ввод в указатель и возвращение методов этого указателя? - PullRequest
1 голос
/ 23 ноября 2011

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

shape *s = (shape *) 0;
cin >> *s;
if (s)
    cout << "Shape" << (*s) << '\n';
else if (! cin.bad())
    cout << "Read reached EOF\n";
else
    cout << "Read failed\n";

Я перегрузил оператор <<, например,вызывает метод рисования любой формы; </p>

std::ostream& operator<< (std::ostream &os, shape &s){
    s.draw();
    return os;
}

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

< Circle: (3,1) 1 >

Я перегружен оператор >>;

std::istream& operator>> (std::istream &is, shape &s){
  char lessthan, greaterthan, opbrkt, clsbrkt, comma;
  string shape_type;
  double x1, y1, r, x2, y2, x3, y3;

  if (is >> lessthan) {
    if ('<' != lessthan) {
      is.setstate(ios::badbit);
      return is;
    }

    //Circle implemntation
    if(is >> shape_type && shape_type == "Circle:"){
      if(!((is >> opbrkt) && (opbrkt = '('))) {
        is.setstate(ios::badbit);
        return is;
      }

      cout << "Yes" << i++;
      if(!(is >> x1)){
        is.setstate(ios::badbit);
        return is;
      }

      if(!(is >> comma && comma == ',')){
        is.setstate(ios::badbit);
        return is;
      }

      if(!(is >> y1)){
        is.setstate(ios::badbit);
        return is;
      }


      if(!(is >> clsbrkt && clsbrkt == ')')) {
        is.setstate(ios::badbit);
        return is;
      }

      if(!(is >> r)){
        is.setstate(ios::badbit);
        return is;
      }

      if(!(is >> clsbrkt && clsbrkt == '>')) {
        is.setstate(ios::badbit);
        return is;
      }
    }

    return is;
  }

  return is;
}

Это в основном обнаруживает, что это круг и помещает соответствующие впеременные для последующего использования, но как мне получить эти данные в указателе 's', чтобы указать, что теперь должно быть объектом круга?

Ответы [ 2 ]

1 голос
/ 23 ноября 2011

Ой !!!

shape *s = (shape *) 0;
cin >> *s;

Вы просто разыменовали нулевой указатель. Это неопределенное поведение. Вам нужен фабричный метод.

shape* input()
{
    string name;
    cin >> name;
    if(name == "circle")
    {
       double radius;
       cin >> radius;
       return new Circle(radius)
    }
    else if(name == "Rectangle")
    {
        ....
        return new Rectangle(...);
    }
    else if .... 

}
1 голос
/ 23 ноября 2011

Вы не можете прочитать в указатель.Вы можете читать только в объект:

shape s;
std::cin >> s;

// if you need a pointer for some reason:
shape * p = &s;

Если реальный объект полиморфен по своей природе, вы можете создать класс-оболочку, возможно, так:

class Shape
{
  ShapeImpl * impl;  // or better, `std::unique_ptr<ShapeImpl>`
  //
}

class ShapeImpl { virtual ~ShapeImpl() { } };
class Circle : public ShapeImpl { /* ... */ }

В противном случае,Вы можете просто отказаться от идеи перегрузки оператора извлечения потока и вместо этого предоставить собственную функцию десериализации:

std::unique_ptr<Shape> read_shape(std::istream & is)
{
  // ...
  std::unique_ptr<Shape> p(new Circle);
  // ...
  return p;
}

std::unique_ptr<Shape> s(read_shape(std::cin));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...