几个需要清晰理解的概念

来源:互联网 发布:夏普电视机知乎 编辑:程序博客网 时间:2024/04/29 23:59
1  名称覆盖

    子类若定义了与基类成员名称相同的成员,则基类成员在子类中会被覆盖。这里要理解的是C++的名称掩盖规则(name-hiding rules)是很简单的:只看名称,不区别类型。

    此外,如果基类中存在某个成员函数的若干个重载版本,而子类也定义了同名函数(参数类型与返回值是否一致都不重要),则基类所有版本的重载函数都会被覆盖。

    例如,下面例子中基类的成员x和 foo()都会被子类中的对应成员所覆盖,尽管它们的类型并不相同

   
class Base
{
public:
   
int x;
   
void foo(){}
    
}
;

class Derived:public Base
{
public:
   
float x;
   
int foo()return 1;}
}
;

2     virtual 函数在通过指针或引用调用时编译器进行动态绑定,然而在处理其默认参数值的时候确实静态绑定。

    上面这句话的意思是说,尽管执行的函数体是由指针(引用)所指向的对象的类型来决定,但函数的默认参数却是由指针(引用)本身的类型所决定的。

3     重载函数的解析调用规则

    首先从候选者中选出唯一的最佳匹配者,然后再检查这个最佳匹配者的可用性(访问合法性)。

    这就意味着如果在第一阶段中存在两个最佳匹配的话,即便程序员可以根据二者是否可用来得出该选取那个版本,然而编译器并不是如此思考——如果不存在唯一的最佳匹配的话,它认为存在歧义,拒绝继续下一个步骤,直接报告匹配失败。

4
    在public继承方式中,当某个函数需要的参数类型为基类而调用者传入一个子类时,编译器会执行隐式的类型转换以保证函数的调用成功,这样才能从语义上保证public继承所表示的"is-a"关系。

    而在private继承方式中,编译器不会自动的将子类对象转换为一个基类对象。

    对于难以理解的protected继承,编译器同样不提供自动转型

5   拷贝构造函数的声明

    一般情况下都应写成"Base(const Base &);",而不是"Base(Base &);"
   
6 自增、自减运算符的前缀和后缀形式

    对于用户自定义类型,应该优先使用前缀形式,因为其不用构造临时对象,效率更高;而且通常后缀形式的实现也是以前缀为基础的。

7 优先使用运算符的赋值组合形式,这样的效率更高,例如,优先使用"a+=b;"而不是"a=a+b;",而且对于用户自定义类型,在运算符重载时,通常是以"@+="为基础来实现"@"。


8  参数传递中的传值和引用

    对于用户自定义类型,特别是复杂类型,应优先考虑采取引用形式,这样可以避免传值情况下拷贝构造函数和析构函数带来的开销。

    而对于内置类型,应优先考虑采用传值形式,因为引用的底层实现就是指针,而通过指针进行访问,效率较低。

   
原创粉丝点击