c++---类的内联函数,const修饰的函数,友元函数,静态成员

类的内联函数,const修饰的函数,友元函数,静态成员

一.类的内联函数。

内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。

1.在类中被inline修饰的函数就是内联函数。在编译时,它将展开在所有调用它的地方。不需要形成函数栈帧,所以节省了成本。就可以提高程序的运行效率。

2.内联函数是用空间换取时间的一种做法,在调用之处全部展开,使用了空间,但是却节省了函数压栈出栈的时间。所以内联函数只适用于代码幅度短的函数。若是代码长度偏长或者代码短但是有循环或者递归的就不适宜作为内联函数。

3.inline只是编写程序者对编译器的一种建议,有可能编写者定义了这个函数为内联函数,但是编译器认为它不可以用作内联函数,就将这个请求忽略,这样这个函数还不能作为内联函数来使用。

4.inline必须是在函数定义的时候定义,若是定义这个函数时没有定义为内联函数,其余时间在函数前用inline修饰也是没有作用的。

5.在c++类中定义的函数默认为是内联函数。不需要显式的用inline修饰,但是一般韩式写着,比较清楚些,以免有时会有遗忘。

  在写代码的时候尽量用const /enum /内联 /代替宏定义,为什么呢?下面我们说一下宏定义的优缺点
宏的优点:

  1. 增强代码的复用性。
  2. 提高性能

宏的缺点:

  1. 不方便调试宏(因为在预编译期间就进行了替换)
  2. 导致代码的可读性差,可维护性差,容易误用。
  3. 没有类型安全的检查。
二.类中被const修饰的成员函数。

   之前我接触过的都是const修饰某个变量,使这个变量不能被改变,具有了常性。在c++中,const还可以被用来修饰函数。就像是下面这个样子,

class Date
{
public:
//    ①
    void show()
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
//    ②
    void show() const
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
//    ③
    //void show(const Date* this)
    //{
    //    cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    //}
private:
    int _year;
    int _month;
    int _day;
};

在上面这段代码中,第二个是被const修饰的函数正确写法。第三个函数是编译器对第二个函数进行编译器处理后的结果。这样来看const还是修饰的变量。它要保证传进函数的对象不被函数改变。这样在类中就会有const函数,非const函数,const对象和非const对象,在这些范围里,就会产生调用与被调用的关系,那么在什么情况下谁可以调用谁,谁不可以调用谁,下面做一个总结。。

  1. const对象可以调用const的函数,const的函数也可以调用const函数
  2. 非const对象可以调用非const函数,非const函数也可以调用非const函数
  3. 非const对象可以调用const函数。非const函数不可以调用const函数
  4. const对象不可以调用非const函数,const函数可以调用非const函数

  处理这类问题只需要记得,const的权限只能缩小不可以扩大。若是const的函数就要保证传进来的对象不可以被改变,所以它内部不可以调用非const函数。其余也都是类似的思路。

三.友元函数。

友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend。

友元函数一般就是在函数声明前加一个friend修饰,在类内进行声明,在类外定义。

class Date
{
public:
    friend void show(const Date& d);
    void show()
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
private:
    int _year;
    int _month;
    int _day;
};
void show(const Date& d)
{
        cout<<d._year<<"-"<<d._month<<"-"<<d._day<<endl;
}

上面的用friend修饰的show函数就是友元函数,在类内声明在类外定义。它可以访问d的成员变量。即使它不是成员函数。所以,由此看来,友元会破坏类的封装性。一般情况下不要使用,但是有时候只能使用友元函数才能达到想要的功能,举个例子,

就像是要重载输出运算符<<。就必须使用友元函数,为什么不可以使用成员函数重载呢?因为在类中重载的运算符函数的第一个参数都是隐含的this指针所指向的对象,但是输出运算符的第一个操作数是不是对象。所以就不可以使用成员函数重载。
下面这就是重载的输出运算符

class Date
{
public:
    friend ostream& operator<<(ostream& os,const Date& d);
private:
    int _year;
    int _month;
    int _day;
};
ostream& operator<<(ostream& out,const Date& d)
{
    out<<"year:"<<d._year<<endl;
    out<<"month:"<<d._month<<endl;
    out<<"day:"<<d._day<<endl;
    return out;
}
四.类的静态成员。

  在类中被static修饰的成员,就是类的静态成员。类的静态成员与类的成员函数比较相似,类的静态成员是整个类所共享的成员,但是静态成员没有this指针,并不是一个对象对应一个静态成员,而是整个类中的对象的这个静态成员的值都是一样的,若被一个改变,则所有对象的这个静态成员都被改变。
   类中的静态成员可以是静态成员函数,也可以是静态成员变量。若是静态成员变量,则所有的对象的这个成员变量都一样。静态的成员变量只能由静态的成员函数来调用,因为静态的成员变量是共享的,所以它就只对应一个变量,所以,静态成员函数没有this指针。这个函数也不可以调用其它的成员函数和成员变量。
  可以直接使用类型作用域访问符直接调用静态成员函数。

Date::PrintCount();
发布了65 篇原创文章 · 获赞 31 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章