【问题标题】:Derive a class from two same-Derived classes从两个相同的派生类派生一个类
【发布时间】:2017-05-04 11:35:45
【问题描述】:

exercise.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_ */

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 对象时,我只得到了默认值。虽然我初始化了派生类。还有一件事。事实上,我们分别派生了 Rectangle 和 Triangle,并从这些对象派生了另一个对象。编译器将如何决定使用哪个 area() 函数?

【问题讨论】:

  • 你得到哪个输出?您期望哪些价值观?
  • void root::someShape::trySomething() const{ cout

标签: c++ class virtual derived-class


【解决方案1】:

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

查看更多详情: http://www.cprogramming.com/tutorial/virtual_inheritance.html https://isocpp.org/wiki/faq/multiple-inheritance

【讨论】:

    【解决方案2】:

    这里的问题是你有一个从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++ virtual inheritance

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      相关资源
      最近更新 更多