<2008年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

  • 随笔 - 44
  • 文章 - 0
  • 评论 - 86
  • 引用 - 0

常用链接

留言簿(6)

随笔分类(31)

随笔档案(44)

Mining

最新随笔

搜索

  •  

最新评论

阅读排行榜

评论排行榜

深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"

看条款38 的时候不是很理解, 于是写了个测试代码

#include<iostream> 
using namespace std; 

class A{
public:
    
virtual void show(int a=145)
    {
        cout
<<"A: a="<<a<<endl; 
    }   
}; 

class B: public A 

public
    
void show(int b)
    { 
        cout
<<"B: b="<<b<<endl; 
    } 
}; 
class C: public B 

public
    
void show(int c=999)
    { 
        cout
<<"C: c="<<c<<endl; 
    } 
};
class D: public C 

public
    
void show()
    { 
        cout
<<"D:\n"
    }
}; 

void main() 
{
    A 
*pp;
    A a; 
    B b; 
    C c; 
    D d;
    
    a.show();
    pp 
= &a;    pp->show();

    
// b.show();  // error C2660: 'B::show' : function does not take 0 arguments
    pp = &b;    pp->show();
    
    c.show();
    pp 
= &c;    pp->show();

    d.show();
    pp 
= &d;    pp->show();
    
    C 
*pc= &d;
    pc
->show();

    system(
"pause"); 
}   
输出结果是
A: a=145
A: a=145
B: b=145
C: c=999
C: c=145
D:
C: c=145
C: c=999

回顾条款 
虚函数是动态绑定而缺省参数值是静态绑定的.  为什么C++坚持这种有违常规的做法呢?答案和运行效率有关。如果缺省参数值被动态绑定,编译器就必须想办法为虚函数在运行时确定合适的缺省值,这将比现在采用的在编译阶段确定缺省值的机制更慢更复杂。做出这种选择是想求得速度上的提高和实现上的简便,所以大家现在才能感受得到程序运行的高效;

所以
a. 静态绑定 .vs. 动态绑定
A *pp = new B;
这里 pp 静态绑定是 A* , 而动态绑定却是 B*
B *pb = new B;
这里 pb 静态绑定和动态绑定是一样的都是 B*

b. 缺省值是静态绑定的, 而非动态绑定
所以
d.show() 输出 D:  因为show 被 D override

pp = &d;    pp->show();  
pp 被动态绑定到D *, 但是show 的缺省值却是A* 的 145, 所以输出的是 C: c=145, 而不是999 ( 函数 show 被C 给override 了) 

而 C *pc = &d; pc->show() , pc 静态绑定为C*, 而动态绑定为 D* , 所以输出的是 C: c=999 , 999 是 C* 静态绑定的缺省值

c. 所以调用b.show 的时候出现了如下的错误
    // b.show();  // error C2660: 'B::show' : function does not take 0 arguments
因为 B* 没有静态绑定的函数

结论就是 决不要重新定义继承而来的缺省参数值 

ref: 
从这里学了不少:) http://bbs.chinaunix.net/viewthread.php?tid=439188 

posted on 2008-10-06 17:19 泡泡牛 阅读(2805) 评论(6)  编辑 收藏 引用 所属分类: Develop

评论

# re: 深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"  2008-10-06 23:13 陈梓瀚(vczh)

缺省值是编译器绑定的,所以无法动态。而且如果这玩意儿运行期绑定,C++就得提供给你维护那个缺省值实例的方法,这个就太惨了。
  回复  更多评论    

# re: 深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"  2009-09-27 15:44 farawayWind

我也是看到这里才注意到这个问题的。为了实现缺省值的动态绑定,而增加运行开销对于C++这种效率优先的语言是不值得。
书中提到的non-virtual interface是避免该问题,并实现代码重用的一个好方案。
  回复  更多评论    

# re: 深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"  2011-06-21 18:08 那你试试这段代码呢!

#include <iostream>

enum ShapeColor { RED, GREEN, BLUE};

class Shape
{
public:
Shape(){}
virtual void draw(ShapeColor _color = RED) const
{

std::cout<<"I am Shape::draw function , my default color is RED..."<<std::endl;
}
};

class Rectangle : public Shape
{
public:
Rectangle(){}
virtual void draw(ShapeColor _color = GREEN) const
{
std::cout<<"I am Rectangle::draw function , my default color is GREEN..."<<std::endl;
}
};

class Circle : public Shape
{
public:
Circle(){}
virtual void draw(ShapeColor _color = BLUE) const
{
std::cout<<"I am Circle::draw function , my default color is BLUE..."<<std::endl;
}
};


int main ()
{
Shape* ps = new Shape;
Shape* pr = new Rectangle;
Shape* pc = new Circle;
ps->draw();
pr->draw();
pc->draw();
delete ps, pr, pc;
}
  回复  更多评论    

# re: 深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"  2011-09-01 11:11 杜夏威

博主您好!我是新手,问一个比较低级的问题。这一点儿不太明白。
pp = &d; pp->show();
为什么输出的结果是C:c=145呢?D类的show()没有参数,pp被动态绑定到D后,为什么没有输出D:这样的结果,而是选择寻找带有默认参数的函数形式(A类)?
  回复  更多评论    

# re: 深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"  2011-09-01 11:14 杜夏威

再补充问一下,而且为什么输出不是A:a=145呢?可能连续的继承关系我没有搞清楚。还请博主指点一下。谢谢了!
  回复  更多评论    

# re: 深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"  2011-09-02 10:05 杜夏威

哦,我已经弄清楚了!感谢博主写得这篇博客。受益了。歇歇~
  回复  更多评论    

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理