关闭

C++语言中的细节_2

315人阅读 评论(0) 收藏 举报
分类:

//《c++ Primer》笔记 

//P396

可以通过将构造函数声明为explicit,来防止在需要隐式转换的上下文中使用构造函数。(简单来说,就是使用expicit来防止隐式转换)

如:

class A{
public:
      explicit A(int j=0):i(j){}
      int f(const A &a){}
private:
      int i;
};
int main(){
     A a;
     int j;
     a.f(j);  //error:隐式类型转化被explicit阻止,不会调用构造函数来创建一个临时对象,此时f函数的实参只能是类A的对象的引用
}

//P221

内联函数:将函数指定未内联函数,通常就是将它在程序中每个调用点上"内联地"展开。

                    优点:省区调用函数的开销。

                    缺点:1.以代码膨胀为代价。

                                2.每一处内联函数的调用都要复制代码,消耗更多的内存空间。

//P455

转换操作符是一种特殊的类成员函数。

如将类类型转换为标准类型:

class SmallInt{
public:
      SmallInt():i(0){}
      operator int() const {return i;}
private:
       int i;
};
注意: 1.转换函数必须是成员函数

          2.不能指定返回类型

          3.形参表必须为空


// Chapter.15

除了构造函数外,任意非static成员都可以是虚函数。

如果派生类没有重定义某个虚函数,则使用基类中定义的版本。

一旦函数在基类中声明为虚函数,它就一直为虚函数。

派生类可返回基类函数所返回类型的派生类的引用(或指针)。

例:base类可以定义返回 base*的虚函数,

       derived类可以定义返回为base*或derived*。

如果需要声明(但不实现)一个派生类,则声明包含类名但不包含派生列表。

如: 

class Derived;  //虽然Derived类继承Base类,但是声明中不包含派生列表

protected成员可以被派生类对象访问,但不能被该类型的普通用户访问。


动态绑定必须满足的两个条件:

1.只有指定为虚函数的成员函数才能进行动态绑定。

2.必须通过基类类型的引用或指针进行函数调用。

现在就第2点进行分析:

为什么是基类类型,为什么是引用或者指针:

因为可以将派生类对象的引用(或指针)转换未基类子对象的引用(或指针)    //实参是该对象的引用,对象本身未被赋值,并且,转换不会在任何方面改变派生类型对象。

但没有从派生类对象到基类对象的直接转换  //派生类对象可以转换未基类对象,但这是一个间接转换的过程。这将丢弃派生类定义的成员。  

也没有从基类对象(或引用,指针)到派生类对象(或引用,指针)的转换   //从基类转换为派生类,则派生类新定义的部分在这个对象(或引用,指针)内是尚未定义的,而且基类对象并未给派生类的新定义部分分配存储空间。这样则在需要用道派生类的代码时出错。

如果非得从基类到派生类进行转换,在确保这个转换是安全的,就可以使用static_cast强制编译器进行转换。或者,用dynamic_cast申请在运行时进行检查。

如:

Derived d;
Base *bp=&d;
Derived dp=bp;   //error
Derived dp=static_cast<Derived>bp;  //OK

非虚函数总是在编译时根据调用该函数的对象、引用或指针的类型而确定。


覆盖虚函数机制:派生类虚函数调用基类版本时,必须显式使用作用域操作符。


派生类由多个部分组成:派生类本身定义的非static成员+由基类非static成员组成的子对象。


P484  using Base::size;






























0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2258次
    • 积分:87
    • 等级:
    • 排名:千里之外
    • 原创:2篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档
    阅读排行