2016-12-19 3 views
0

exercise.h ist als untenLeiten Sie eine Klasse von zwei gleich Abgeleitete Klassen

#ifndef EXERCISE_H_ 
#define EXERCISE_H_ 

// ROOT namespace 
namespace root{ 

// USHORT definition 
typedef unsigned short ushort; 

// PI DEFINITION 
const double PI = 3.141592; 

class shape { 
    double height; 
    double width; 
public: 
    shape(double h = 1, double w = 1); 
    virtual ~shape(){} 
    double getHeight() const; 
    double getWidth() const; 
    virtual double area() const = 0; 
}; 

class rectangle : virtual public shape{ 
public: 
    rectangle(double height = 1, double width = 1); 
    double area() const; 
}; 

class triangle : virtual public shape { 
public: 
    triangle(double h = 1, double w = 1); 
    double area() const; 
}; 

class someShape : public rectangle, public triangle{ 
public: 
    someShape(double rh = 1, double rw = 1, double th = 2, double tw = 2); 
    double area() const; 
    double trySomething() const; 
}; 




} // NAMESPACE 

#endif /* EXERCISE_H_ */ 

exercise.cpp wie diese

ist
#include <iostream> 
#include <cmath> 
#include "exercise.h" 
using std::cout; 
using std::cin; 
using std::endl; 
using root::ushort; 

// BEGIN SHAPE CLASS 
root::shape::shape(double h, double w) : height(h), width(w){ 

} 

double root::shape::getHeight() const{ 
    return this->height; 
} 

double root::shape::getWidth() const{ 
    return this->width; 
} 
// END SHAPE CLASS 


// BEGIN RECTANGLE CLASS 
root::rectangle::rectangle(double h, double w) : shape(h,w){ 

} 

double root::rectangle::area() const{ 
    return this->getHeight() * this->getWidth(); 
} 

// END RECTANGLE CLASS 
// BEGIN TRIANGNLE CLASS 
root::triangle::triangle(double h, double w) : shape(h,w){ 

} 

double root::triangle::area() const{ 
    return this->getHeight() * this->getWidth()/2; 
} 
// END TRIANGLE CLASS 



root::someShape::someShape(double rh, double rw, double th, double tw) : rectangle(rh,rw), triangle(th,tw){ 

} 

double root::someShape::area() const { 
    return rectangle::area(); 
} 

double root::someShape::trySomething() const{ 
    return triangle::getHeight() * rectangle::getWidth(); 
} 

und in Haupt

#include <iostream> 
#include "exercise.h" 
using std::cout; 
using std::cin; 
using std::endl; 


int main(){ 
    root::shape *ptrShape; 
    ptrShape = new root::someShape(3,2,4,3); 
    cout << "shape area: " << ptrShape->area() << endl; 

    delete ptrShape; 

} 

wenn ich nur ein someShape-Objekt erstelle hat die Standardwerte erhalten. obwohl ich die Ableitungsklasse initiiere. Und da ist noch etwas anderes. Es ist die Tatsache, dass wir Rechteck und Dreieck getrennt abgeleitet haben und aus diesen Objekten ein anderes Objekt abgeleitet haben. Wie wird der Compiler entscheiden, welche area() -Funktion verwendet werden soll?

+0

welche Ausgabe Sie erhalten? Welche Werte erwarten Sie? –

+0

void Wurzel :: someShape :: trySomething() const { \t cout << Dreieck :: getHeight() << "" << Dreieck :: getWidth() << endl; \t cout << rechteck :: getHeight() << "" << rechteck :: getWidth() << endl; } wenn ich dieses benutze, habe ich 1 1 –

Antwort

2

Das hier Problem ist, dass Sie ein virtuelles Erbe von shape zu rectangle und triangle haben, so dass die Konstrukteure von rectangle und triangle nicht shape initialisieren. Ihr someShape Konstruktor entspricht:

root::someShape::someShape(double rh, double rw, double th, double tw) : 
    rectangle(rh,rw), triangle(th,tw), shape() { 

} 

weshalb Sie die Standardwerte 1 und 1 erhalten. Beachten Sie außerdem, dass Sie für das Rechteck und das Dreieck keine anderen height und width speichern können, da Sie virtuelle Vererbung haben.

root::someShape::someShape(double h, double w) : 
    rectangle(h, w), triangle(h, w), shape(h, w) { 

} 

Oder, wenn Sie nicht eine einzelne Instanz shape haben wollen, sollten Sie die virtuelle Vererbung von rectangle und triangle entfernen: Ihr Konstruktor sollte etwas ähnliches sein.

Siehe auch c++ virtual inheritance.

1

Das Problem ist, dass Sie virtuelle Vererbung tun, d. H. Rechteck und Dreieck erben Form mit dem virtuellen Schlüsselwort. Daher gibt es eine einzelne Instanz der Formklasse, die von den abgeleiteten Klassen gemeinsam genutzt wird. Daher werden die Konstruktoraufrufe von Rechteck und Dreieck zu Shape vom Compiler komplett übersprungen.

prüfen diese für weitere Informationen: http://www.cprogramming.com/tutorial/virtual_inheritance.html https://isocpp.org/wiki/faq/multiple-inheritance

Verwandte Themen