wake-up-neo.com

ungültiger neuer Ausdruck des abstrakten Klassentyps

Ich schreibe gerade einen Raytracer für eine Universitätsklasse. Um Szenen aus Dateien zu laden, habe ich einen SD-Loader geschrieben, um SDF-Dateien zu lesen und Szenen dafür zu erstellen.

wenn ich nun den Loader kompilieren möchte, erhalte ich folgende Fehlermeldung:

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]));
                                                      ^

Ich habe versucht, eine Lösung zu finden, schlug aber fehl.

Die sdf_loader-Klasse sieht folgendermaßen aus:

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_;
};

in meiner implementierung des sdf loader habe ich die methode read () geschrieben:

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]));
    }

und für jede andere Form die gleichen.

Wo ist das Problem in meinem Code? Ich sehe es wirklich nicht

Ich verwende g++-4.9 - std=c++0x, um alles zu kompilieren und zu verknüpfen

19
hGen

ungültiger neuer Ausdruck des abstrakten Klassentyps 'box'

Über die Fehlermeldung ist nichts unklar. Ihre Klasse box hat mindestens ein nicht implementiertes Member, was bedeutet, dass es abstrakt ist. Sie können eine abstrakte Klasse nicht instanziieren.

Wenn dies ein Fehler ist, beheben Sie Ihre Box-Klasse, indem Sie die fehlenden Member implementieren. 

Wenn es sich um Design handelt, leiten Sie das Feld ab, implementieren Sie die fehlenden Member und verwenden Sie die abgeleitete Klasse.

43
nvoigt

Wenn Sie C++ 11 verwenden, können Sie den Bezeichner "override" verwenden. Ein Compiler-Fehler wird angezeigt, wenn Sie eine abstrakte Methode nicht ordnungsgemäß überschreiben. Sie haben wahrscheinlich eine Methode, die nicht exakt mit einer abstrakten Methode in der Basisklasse übereinstimmt. Daher überschreiben Sie sie nicht.

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

7
B. Roberts

für andere, die sich am Kopf kratzten, bin ich auf diesen Fehler gestoßen, weil ich eines der Argumente für eine Methode in einer Basisklasse unzureichend const-qualifiziert hatte, sodass die abgeleiteten Klassenmitgliedfunktionen diese nicht überschrieben haben. Stellen Sie also sicher, dass Sie so etwas nicht haben

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

Ein weiterer möglicher Grund für zukünftige Googler

Ich hatte dieses Problem, weil eine Methode, die ich implementieren wollte, eine std::unique_ptr<Queue>(myQueue) als Parameter erfordert, die Queue-Klasse jedoch abstrakt ist. Ich habe das gelöst, indem ich einen QueuePtr(myQueue)-Konstruktor verwendet habe:

using QueuePtr = std::unique_ptr<Queue>;

und verwendet das stattdessen in der Parameterliste. Dies behebt das Problem, da der Initialisierer versucht, eine Kopie von Queue zu erstellen, wenn Sie einen std::unique_ptr seines Typs erstellen, was nicht passieren kann.

2