细读《Effective C++》之九

Chapter 6. Inheritance and Object-Oriented Design

 

条款36:Never redefine an inherited non-virtual function

class  B {
public
:
  
void
 mf();
  ...
};

class D: public
 B {
public
:
  
void
 mf();
 ... 
 };

D x;                              
// x is an object of type D

*pB = &x;                       // get pointer to x
pB->mf();                         // calls B::mf
*pD = &x;                       // get pointer to x
pD->mf();                         // calls D::mf

non-virtual functions是statically bound,此处mf的调用取决于其声明类型而非所指对象;virtual functions是dynamically bound,如果mf是virtual function,其调用将取决于其所指对象,即D。

这儿,出于以下两点原因,Never redefine an inherited non-virtual function:

1) public inheritance应保证is-a关系。

2) non-virtual function的不变性(invariant)应凌驾于特异性(specialization)。

Things to Remember

1) Never redefine an inherited non-virtual function.

条款37:Never redefine a function's inherited default parameter value

redefine a function,那么这个function一定是virtual function了,virtual functions are dynamically bound, but default parameter values are statically bound。

// a class for geometric shapes
class  Shape {
public
:
  
enum
 ShapeColor { Red, Green, Blue };
  
// all shapes must offer a function to draw themselves

  virtual void draw(ShapeColor color = Red) const = 0 ;
  ...
};

class Rectangle: public
 Shape {
public
:
  
// notice the different default parameter value — bad!

  virtual void draw(ShapeColor color = Green) const ;
  ...
};

Shape 
*ps = new Rectangle;       // static type = Shape*, dynamic type = Rectangle*

ps->draw(Shape::Red);            // calls Rectangle::draw(Shape::Red)
ps->draw();                      // calls Rectangle::draw(Shape::Red)!

由于ps的dynamic type是Rectangle,所以解析为Rectangle::draw(),由于ps的static type是Shape,所以解析为Rectangle::draw(Shape::Red)。

因此,应将带default parameter value的函数声明为non-virtual,其实现用一个private virtual function完成:

class  Shape {
public
:
  
enum
 ShapeColor { Red, Green, Blue };
  
void draw(ShapeColor color = Red) const           // now non-virtual

  {
    doDraw(color);                                  
// calls a virtual

  }
  ...

private
:
  
virtual void doDraw(ShapeColor color) const = 0;  // the actual work is

};                                                  // done in this func

class Rectangle: public  Shape {
public
:
  ...

private
:
  
virtual void doDraw(ShapeColor color) const;       // note lack of a

  ...                                                // default param val.
};

Things to Remember

Never redefine an inherited default parameter value, because default parameter values are statically bound, while virtual functions — the only functions you should be overriding — are dynamically bound. 

Item 36 - 37
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PHP 和 JavaScript 都支持 JSON 数据格式,但是在处理 JSON 数据时有一些不同之处。 在 PHP 中,可以使用 `json_encode()` 函数将数组或对象转换为 JSON 格式的字符串,例如: ```php $data = array('name' => 'John', 'age' => 30); $json = json_encode($data); echo $json; // 输出 {"name":"John","age":30} ``` 同样地,在 PHP 中,可以使用 `json_decode()` 函数将 JSON 格式的字符串转换为数组或对象,例如: ```php $json = '{"name":"John","age":30}'; $data = json_decode($json); echo $data->name; // 输出 John ``` 在 JavaScript 中,可以使用 `JSON.stringify()` 方法将对象转换为 JSON 格式的字符串,例如: ```javascript var data = {name: 'John', age: 30}; var json = JSON.stringify(data); console.log(json); // 输出 {"name":"John","age":30} ``` 同样地,在 JavaScript 中,可以使用 `JSON.parse()` 方法将 JSON 格式的字符串转换为对象,例如: ```javascript var json = '{"name":"John","age":30}'; var data = JSON.parse(json); console.log(data.name); // 输出 John ``` 需要注意的是,在 PHP 中,可以将 JSON 格式的数据直接解码为关联数组或对象,而在 JavaScript 中,解析 JSON 数据时始终会得到一个对象。如果要得到关联数组,则需要手动处理。例如,在 JavaScript 中,可以将解析后的对象转换成关联数组: ```javascript var json = '{"name":"John","age":30}'; var data = JSON.parse(json); var dataArray = []; for (var key in data) { dataArray.push({key: key, value: data[key]}); } console.log(dataArray); // 输出 [{key:"name",value:"John"},{key:"age",value:30}] ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值