2016-06-14 15 views
-4

Ich arbeite an dem Erbe und Polymorphismus Mechanismus in C++, und ich habe ein unlösbares Problem aus meiner Sicht.
Eigentlich vermute ich, ich vermisse etwas sehr einfaches, aber ich kann nicht herausfinden, was es ist.
Kann mir bitte jemand helfen? HierC++ allgemeine Vererbung Missverständnis

ist das Problem:

Ich habe eine Basisklasse namens Article und eine abgeleitete Klasse mit dem Namen ArticleEnSolde und eine dritte Klasse Caddy, die eine Tabelle von Article.Article verwalten enthält nur ein string und ein int und ArticleEnSolde hat ein Rabattsystem basierend auf Prozent.

Caddy enthält nur die Article Tabelle und haben eine Methode namens prixTotal(), die die Summe des Artikelpreises zurückgibt.
Aber ich kann nicht herausfinden, wie aber alle Objekte als Article angesehen werden, anstatt als ArticleEnSolde` betrachtet zu werden.
Und die Gesamtsumme ist falsch. Hier

ist Article.hpp

#include <iostream> 
#pragma once 

using namespace std; 

class Article{ 
private: 
    string nom; 
    float prix; 

public: 
    Article(string = "vide",float = -44.6); 
    void set_nom(string); 
    void set_prix(float); 
    string get_nom() const; 
    virtual float getPrix() const; 
    friend ostream& operator<<(ostream&,Article&); 
    virtual ~Article(); 
}; 

Hier Article.cpp ist

#include "Article.hpp" 

Article::Article(string n,float p):nom(n),prix(p){} 

void Article::set_nom(string s){ 
    this->nom = s; 
} 

void Article::set_prix(float p){ 
    this->prix = p; 
} 

string Article::get_nom() const{ 
    return this->nom; 
} 

float Article::getPrix() const{ 
    return this->prix; 
} 

ostream& operator<<(ostream& o ,Article& a){ 
    o << "nom article : " << a.get_nom() << " prix : " << a.getPrix(); 
    return o; 
} 

Article::~Article(){ 
    cout << "appel du destructeur d'article " << endl; 
} 

Hier ist ArticleEnSolde.hpp

#include "Article.hpp" 
#pragma once 

class ArticleEnSolde : public Article{ 

private: 
    float remise; 

public: 
    ArticleEnSolde(string,float,float); 
    float get_remise() const; 
    void set_remise(float); 
    float getPrix(); 
    friend ostream& operator<<(ostream&,ArticleEnSolde&); 
}; 

Hier ist ArticleEnSolde.cpp

#include "ArticleEnSolde.hpp" 


ArticleEnSolde::ArticleEnSolde(string s,float f,float i):Article(s,f),remise(i){} 

float ArticleEnSolde::get_remise() const{ 
    return this->remise; 
} 

void ArticleEnSolde::set_remise(float r){ 
    this->remise = r; 
} 

float ArticleEnSolde::getPrix(){ 
    cout << "ArticleEnSolde " << endl; 
    Article * p = this; 
    return p->getPrix() * (1 - this->get_remise()); 
} 

ostream& operator<<(ostream& o ,ArticleEnSolde& a){ 
    Article * p = &a; 
    o <<"nom ArticleEnSolde " << p->get_nom() << " prix : " << p->getPrix() << " remise : " << a.get_remise() << " prix apres reduction " << a.getPrix(); 
    return o; 
} 
Hier

ist Caddy.hpp

#include "Article.hpp" 
#include "ArticleEnSolde.hpp" 

class Caddy{ 
private: 
    Article ** tableau; 
    int index; 
    int taille_max; 

public: 
    Caddy(int); 
    Article** get_tab(); 
    int get_index() const; 
    void set_index(int); 
    int get_taille_max() const; 
    Article* get_article(int); 
    void add_article(Article&); 
    float prixTotal(); 
    friend ostream& operator<<(ostream&,Caddy&); 
// ~Caddy(); 
}; 

Hier Caddy.cpp ist

#include "Caddy.hpp" 

Caddy::Caddy(int i):taille_max(i),index(0){ 
    tableau = new Article *[i]; 
} 

Article** Caddy::get_tab(){ 
    return this->tableau; 
} 

int Caddy::get_index() const{ 
    return this->index; 
} 

void Caddy::set_index(int a){ 
    this->index = a; 
} 

int Caddy::get_taille_max() const{ 
    return this->taille_max; 
} 

Article* Caddy::get_article(int a){ 
    return this->tableau[a]; 
} 

void Caddy::add_article(Article& a){ 
    if(this->index <this->taille_max){ 
     cout << "inferieur" << endl; 
     this->tableau[this->index++] = &a; 
     cout << "ajout reussi" << endl; 
     cout << this->index << endl; 
    } 
    else{ 
     cout << "ajout refuse " << endl; 
    } 
} 

float Caddy::prixTotal(){ 
    float somme = 0; 
    for(int i =0;i<this->get_index();i++){ 
     cout << this->get_tab()[i]->getPrix() << endl; 
    } 
    return somme; 
} 

ostream& operator<<(ostream& o,Caddy& c){ 

    for(int i = 0 ;i<c.get_index();i++){ 
     o << "Case " << i <<" " << c.get_tab()[i] << endl; 
    } 
    return o; 
} 

/* 
    Caddy::~Caddy(){ 
     cout << "appel du destructeur " << endl; 
     for(int i = 0 ; i < this->get_index();i++){ 
      this->get_tab()[i].~Article(); 
     } 
    }  
*/ 

Und schließlich ist hier der Hauptcode:

#include "Article.hpp" 
#include "ArticleEnSolde.hpp" 
#include "Caddy.hpp" 

int main(){ 
    Article a("a",12); 
    ArticleEnSolde b("b",15,0.2); 
    cout << a << endl; 
    cout << b << endl; 
    Caddy c(2); 
    c.add_article(a); 
    c.add_article(b); 
    cout << c << endl; 
    cout << "prix total : " << c.prixTotal() << endl; 
} 

ich am Ende haben wollen " prix total 24 "statt 27 bitte kann mir jemand helfen?

Dank

+0

Sie meinen, [ "Vererbung"] (http://ell.stackexchange.com/questions/22529/Erbe und Erbe). –

+0

Ja, ich wusste nicht, dass es einen Unterschied gab – kevin556

+2

Ihr ArticleEnSolde :: getPrix() ist ein bisschen rekursiv (zum Glück ist es nicht wirklich aufgerufen) ... Warum verwenden Sie nicht stattdessen Member veariables? –

Antwort

2

Auf einen Blick sieht, wie das Problem ist, sind wirklich getPrix() zwingende Sie nicht.

In Article:

virtual float getPrix() const; 

In ArticleEnSolde:

float getPrix(); 

Der Unterschied ist, ist man const, aber andere nicht, so dass sie nicht die gleiche Methode in der Tat! Machen Sie beide const und das sollte das beheben. Denken Sie auch daran, der Methodendefinition in der .cpp-Datei auch const hinzuzufügen.


Und vorausgesetzt, Sie ein modernes C++ Compiler verwenden (sollten), die Sie hinzugefügt C++ 11 override Schlüsselwort zu dem außer Kraft gesetzt ArticleEnSolde Methode haben könnte:

float getPrix() const override; 

Dann würden Sie bekommen Compiler haben Fehler, wenn Sie die const verpasst haben (denn dann wäre es nicht überschrieben worden).


Und wenn Sie, dass repariert werden Sie die Rekursion hier reparieren müssen:

float ArticleEnSolde::getPrix() const { 
    cout << "ArticleEnSolde " << endl; 
    // pointless: Article * p = this; 
    // infinite recursion: return getPrix() * (1 - this->get_remise()); 
    // Here's how you call superclass method explicitly: 
    return Article::getPrix() * (1 - this->get_remise()); 
} 
+2

Noch besser, fügen Sie "override" zur übergeordneten Deklaration hinzu. –

+0

@KerrekSB Danke, dass Sie das herausgebracht haben, bearbeitet. – hyde

+0

danke euch allen – kevin556