2016-12-19 17 views
0

exercise.h как нижеНаследуйте класс из двух одинаковых классов-Derived

#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 подобно этому

#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(); 
} 

и в главной

#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; 

} 

, когда я создаю объект someShape i only получили значения по умолчанию. хотя я инициализирую класс вывода. И есть другое. Это факт, что мы вывели Прямоугольник и Треугольник отдельно, и из этого объекта мы получили другой объект. Как компилятор решит, какую функцию area() использовать?

+0

, какой выход вы получаете? какие значения вы ожидаете? –

+0

void root :: someShape :: trySomething() const { \t cout << triangle :: getHeight() << "" << triangle :: getWidth() << endl; \t cout << прямоугольник :: getHeight() << "" << прямоугольник :: getWidth() << endl; } , когда я использую это, я получил 1 1 –

ответ

2

Проблема здесь состоит в том, что у вас есть виртуальный наследство от shape до rectangle и triangle, поэтому конструкторы rectangle и triangle не инициализирует shape. Ваш someShape конструктор эквивалентен:

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

} 

Именно поэтому вы получите значения по умолчанию 1 и 1. Также обратите внимание, что поскольку у вас есть виртуальное наследование, вы не можете хранить разные height и width для прямоугольника и треугольника. Ваш конструктор должен быть что-то вроде:

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

} 

Или, если вы не хотите иметь один экземпляр shape, вы должны удалить виртуальное наследование rectangle и triangle.

См. Также c++ virtual inheritance.

1

Проблема в том, что вы выполняете виртуальное наследование, т. Е. Прямоугольник и треугольник наследуют форму, используя ключевое слово virtual. Таким образом, существует один экземпляр класса формы, который разделяется между производными классами. Следовательно, вызов конструктора из прямоугольника и треугольника в форму полностью пропускается компилятором.

Проверить это для более подробной информации: http://www.cprogramming.com/tutorial/virtual_inheritance.html https://isocpp.org/wiki/faq/multiple-inheritance