недопустимое новое выражение типа абстрактного класса

В настоящее время я пишу raytracer для университетского класса. Чтобы загрузить сценарии из файлов, я написал sdfloader для чтения файлов sdf и создания для них сцен.

если теперь я хочу скомпилировать загрузчик, я получаю следующую ошибку:

rc/sdf_loader.cpp: In member function 'void SDFloader::add_shape(std::istringstream&)':
src/sdf_loader.cpp:95:58: error: invalid new-expression of abstract class type 'box'
                                &scene_.materials[mat]));
                                                      ^

Я попытался найти решение, но не смог.

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

class SDFloader {
  public:
    SDFloader();
    ~SDFloader();

    Scene const& scene() const;
    void read(std::string file);

  private:
    void add_material(std::istringstream&);
    void add_shape(std::istringstream&);
    void add_light(std::istringstream&);
    void add_camera(std::istringstream&);
    void apply_transformation(std::istringstream&);

  private:
    Scene scene_;
};

в моей реализации загрузчика sdf я написал метод read():

void SDFloader::add_shape(std::istringstream& iss) {

    std::string name;
    iss >> name;

    if(name == "box") {
      double x1,y1,z1,x2,y2,z2;
      std::string mat;
      iss >> name >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> mat;
      scene_.shapes.insert(new box(point(x1,y1,z1),
                                   point(x2,y2,z2),
                                   name,
                                   &scene_.materials[mat]));
    }

и для каждой другой формы одни и те же звонки.

Где проблема в моем коде? Я действительно этого не вижу

Я использую g++-4.9 - std=c++0x чтобы скомпилировать и связать все

Ответ 1

недействительное новое выражение типа абстрактного типа "box"

В сообщении об ошибке нет ничего непонятного. В box класса есть хотя бы один член, который не реализован, что означает, что он абстрактный. Вы не можете создать абстрактный класс.

Если это ошибка, исправьте свой класс ящиков, внедряя отсутствующие элементы.

Если это по дизайну, вывести из окна, реализовать отсутствующий элемент и использовать производный класс.

Ответ 2

Если вы используете С++ 11, вы можете использовать спецификатор "override", и он даст вам ошибку компилятора, если вы неправильно переопределяете абстрактный метод. Вероятно, у вас есть метод, который точно не соответствует абстрактному методу в базовом классе, поэтому вы на самом деле не переопределяете его.

http://en.cppreference.com/w/cpp/language/override

Ответ 3

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

class Base 
{
  public:
      virtual void foo(int a, const int b) = 0;
}
class D: public Base 
{
 public:
     void foo(int a, int b){};
}

Ответ 4

Еще одна возможная причина для будущих гуглеров

У меня была эта проблема, потому что метод, который я пытался реализовать, требовал в качестве параметра std::unique_ptr<Queue>(myQueue), но класс Queue является абстрактным. Я решил, что с помощью конструктора QueuePtr(myQueue):

using QueuePtr = std::unique_ptr<Queue>;

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