从两个相同的类中得出一个类

Derive a class from two same-Derived classes

本文关键字:一个 两个      更新时间:2023-10-16

corest.h 如下

#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_ */

练习.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();
}

,在Main

#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对象时,我只会得到默认值。尽管我启动了派生班。还有另一件事。事实是,我们分别得出了矩形和三角形,并且从那些对象中得出了另一个对象。编译器将如何确定要使用的区域()函数?

这里的问题是您具有从shaperectangletriangle的虚拟继承,因此rectangletriangle的构造函数不初始化shape。您的someShape构造函数等于:

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

这就是为什么您获得默认值11的原因。另外,请注意,由于您具有虚拟继承,因此无法为矩形和三角形存储不同的heightwidth。您的构造函数应该是:

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

或如果您不想拥有shape的单个实例,则应删除rectangletriangle的虚拟继承。

另请参见C 虚拟继承。

问题在于您正在使用虚拟的矩形和三角形继承形状,使用虚拟关键字。因此,在派生类之间共享一个形状类的实例。因此,从矩形和三角形到形状的构造函数完全跳过了编译器。

检查此信息以获取更多详细信息:http://www.cprogramming.com/tutorial/virtual_inheritance.htmlhttps://isocpp.org/wiki/faq/multiple-inheritance

相关文章: