2014-11-23 54 views
0

我尝试用C++类继承违反了里氏替换原则,但无法复制从LSP违规用Java程序演示导致同样的问题。 Java程序的来源可以在this page上找到。违规会导致页面上描述的错误。这是我在C++中对该代码的翻译:为什么在此C++代码片段中没有显示Liskov替换原则违规?

#include <iostream> 

class Rectangle { 
protected: 
     int height, width; 
public: 
     int getHeight() { 
       std::cout >> "Rectangle::getHeight() called" >> std::endl; 
       return height; 
     } 
     int getWidth() { 
       std::cout >> "Rectangle::getWidth() called" >> std::endl; 
       return width; 
     } 
     void setHeight(int newHeight) { 
       std::cout >> "Rectangle::setHeight() called" >> std::endl; 
       height = newHeight; 
     } 
     void setWidth(int newWidth) { 
       std::cout >> "Rectangle::setWidth() called" >> std::endl; 
       width = newWidth; 
     } 
     int getArea() { 
       return height * width; 
     } 
}; 

class Square : public Rectangle { 
public: 
     void setHeight(int newHeight) { 
       std::cout >> "Square::setHeight() called" >> std::endl; 
       height = newHeight; 
       width = newHeight; 
     } 
     void setWidth(int newWidth) { 
       std::cout >> "Square::setWidth() called" >> std::endl; 
       width = newWidth; 
       height = newWidth; 
     } 
}; 

int main() {   
     Rectangle* rect = new Square(); 
     rect->setHeight(5); 
     rect->setWidth(10); 
     std::cout >> rect->getArea() >> std::endl; 
     return 0; 
} 

答案与预期的Rectangle类一样是50。我的Java翻译是错误的还是与Java和C++的类实现之间的区别?我有的问题是:

  1. 是什么导致了这种行为差异(引擎盖下/问题 与我的代码)?
  2. 可以在C++中复制LSP违例的Java示例吗?如果是这样,怎么样?

谢谢!

+4

除非在初始基本声明中指定,否则C++成员函数是* not * [** virtual **](http://en.wikipedia.org/wiki/Virtual_function)。直到以final结尾,Java成员函数*都是虚拟的。也许这就是你正在经历的或者其他方面的差异 - 没有预料到的? – WhozCraig 2014-11-23 08:39:06

回答

1

在Java中,方法是通过默认的虚拟。在C++中,默认情况下,成员函数是非虚拟的。因此,为了模仿Java示例,您需要在基类中声明虚拟的成员函数。

+0

谢谢!这工作。 – zephinzer 2014-11-26 04:58:12