web-dev-qa-db-fra.com

nouvelle expression invalide de type classe abstraite

J'écris actuellement un traceur de rayons pour une classe universitaire . Afin de charger des scènes à partir de fichiers, j'ai écrit un sdfloader afin de lire des fichiers sdf et de créer des scènes à cet effet.

si je veux maintenant compiler le chargeur, j'obtiens l'erreur suivante:

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

J'ai essayé de trouver une solution mais j'ai échoué.

La classe sdf_loader ressemble à ceci:

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

dans mon implémentation du chargeur sdf, j’ai écrit la méthode 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]));
    }

et pour toute autre forme, les mêmes appels.

Où est le problème dans mon code? Je ne le vois vraiment pas

J'utilise g++-4.9 - std=c++0x pour tout compiler et lier

19
hGen

nouvelle expression non valide du type de classe abstrait 'box'

Le message d'erreur n'a rien de flou. Votre classe box a au moins un membre qui n'est pas implémenté, ce qui signifie qu'il est abstrait. Vous ne pouvez pas instancier une classe abstraite.

S'il s'agit d'un bogue, corrigez votre classe box en implémentant le ou les membres manquants. 

Si c'est le cas, dérivez de box, implémentez le ou les membres manquants et utilisez la classe dérivée.

43
nvoigt

Si vous utilisez C++ 11, vous pouvez utiliser le spécificateur "override", qui vous donnera une erreur de compilation si vous ne redéfinissez pas correctement une méthode abstraite. Vous avez probablement une méthode qui ne correspond pas exactement à une méthode abstraite dans la classe de base, vous ne la remplacez donc pas réellement.

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

7
B. Roberts

pour d’autres se gratter la tête, j’ai rencontré cette erreur parce que j’avais mal qualifié l’un des arguments d’une méthode dans une classe de base, de sorte que les fonctions de membre de la classe dérivée ne l’écrasaient pas. alors assurez-vous que vous n'avez pas quelque chose comme

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

Une autre cause possible pour les futurs googleurs

J'avais ce problème parce qu'une méthode que j'essayais d'implémenter nécessitait un std::unique_ptr<Queue>(myQueue) en tant que paramètre, mais la classe Queue est abstraite. J'ai résolu ce problème en utilisant un constructeur QueuePtr(myQueue) comme ceci:

using QueuePtr = std::unique_ptr<Queue>;

et utilisé cela dans la liste de paramètres à la place. Cela résout le problème car l'initialiseur essaie de créer une copie de Queue lorsque vous créez un std::unique_ptr de ce type, ce qui est impossible.

2
Jonathan Landrum