C++知识点随笔(三):static、const、friend、inline

原创 2015年07月07日 09:24:18

一、static

静态成员属性为什么要在类外初始化?
静态成员属性之所以不能在构造函数内初始化,是因为构造函数必须要在定义对象的时候才会调用,而static变量在编译的时候就创建了,所以要在类外通过类名作用域对static成员属性初始化。

注意:sizeof()在C++中和C语言有不同,当我们:

cout << sizeof(//类名) << endl;

的时候,不是输出这个类的大小,而是输出定义一个这个类的对象需要申请多大的空间,所以如果这个类里包含了静态成员都不会计算在sizeof()内的,因为静态成员一个类只有一份儿,所以的对象共用他们。

struct Node
{
    int age;
    char c;
};

class CPeople
{
public:
    int pp;
    static const int qq = 100;   //静态常量整形数据成员才能在类内初始化
    static Node node[2];
    static int num;    // 静态成员一定要在类外初始化
public:      //相当于全局变量,在编译的时候就申请空间了,不用对象也能调用,(类名::)
    CPeople()
    {
        pp = 100;
    }
    //  静态成员函数:不能用普通的成员属性,只能用 static 成员,因为没有this指针
    static void Show()
    {
        //cout << this->pp << endl;     
        cout << num << endl;
        cout << "static::show" << endl;
    }
};
Node CPeople::node[2] = {{123,'d'},{456,'y'}};  //静态结构体数组初始化
int CPeople::num = 123;   //静态成员的初始化

注意:静态常量整形数据成员才能在类内初始化。所以short、long、char都可以,但是float、double不可以。

二、const

非静态const成员属性为什么一定要在初始化列表里进行初始化?
在C中我们知道#define进行预定义的某个数是被分配内存的,其文件在编译预处理过程中就会用定义好的数据去替代文中的符号。但是const却是不一样的,一般情况下编译器也是不为const创建空间的,只是将这个定义的数字保存在符号表中的。所以C++中const是在编译的时候定义的,但是它的初始化可以在调用构造函数(也就是创建对象)的时候通过初始化列表的方式进行。调用构造函数的时候,首先是给该实例(类的具体对象)分配空间。使用初始化列表的话,就在分配空间的时候,同时将其空间初始化。但在构造函数的大括号里,所有变(常)量的空间都已经分配好了,进行赋值操作。我们知道const是常量,只能进行初始化操作而不能进行赋值操作,所以必须在初始化列表中分配空间的同时进行初始化操作。

还有一个赋值次数,效率上的区别,初始化列表在对象初始化时对成员变量赋值一次,而使用构造函数内直接赋值的话,对成员变量赋值两次,一次是对象构造是用默认值进行赋值,第二次是调用构造函数赋值。因为普通成员变量是否初始化都可以,而且允许赋值操作,所以普通成员变量既可以使用初始化列表又可以使用构造函数赋值。

参考:http://blog.csdn.net/zhouyelihua/article/details/23252667

const成员函数

void Show(/*const CPeople* this*/) const   // 常函数,不能修改类中的成员属性
{                               
    //this->a = 100;   //错误,因为 this 已经变成 const CPeople* this
}

常量类型的对象:

const CPeople pep;

只能调用常函数,普通函数用不了,因为我们知道成员函数在使用的时候要把对象的地址传进去,而我们用常量对象调用普通成员变量的时候,相当于:

void AA(/*CPeople* this = const CPeople* ll*/)
{
    a = 567;
}

一定会报错的。而const成员函数的this已经变了,所以常量对象可以调用const成员函数。反过来普通对象可以调用常函数。

三、friend

friend class BB;                // 友元类
friend void Show(CPeople pp);   // 友元函数,可以让这个东西用自己的private成员

无论是友元类还是被友元类,都不能继承这个友元关系。友元的友元也不能使用。友元就是只限定这一个可以用

类的封装性问题
友元函数是破坏类的封装性的最大杀手。我们在使用成员函数返回类的私有成员属性的时候也是很危险的,如果一定要使用的话,就将返回值设为const。

四、inline

void AA()    // 类内实现的都是内联函数(默认的)
{
    cout << "AA" << endl;
}
/*inline */void BB();    //  不是内联的 
inline void BB();    //  内联的

不过编译器自己也会有判断,其实声明为inline只是对编译器提出一个建议,建议编译器进行内联,而具体会不会内联,由编译器决定,编译器会综合考虑更方面因素来判断要不要进行内联。
内联将函数代码直接在调用的地方展开,而函数调用是一个跳转语句,通过函数指针跳转到函数体的地址,执行完再回来,所以inline是一种用空间换时间的方法。

参考我的另一篇博客:http://blog.csdn.net/u012300157/article/details/46763089

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C++中 inline 和friend 关键字的作用

1:inline函数叫内联函数。一般来说,C++函数调出使用的时候,是去找函数的地址,可是假如是1个很容易的函数,并且常常调出使用的话,这样会比较慢,全部要再函数声明的时候在前面加上inline关键字...

C++中的inline关键字

在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数。 内联函数的引入有利有弊,使用时应当注意。...

C++反射类和成员函数的实现

原文地址: C++反射类和成员函数的实现,需要用到STL标准模板库
  • ihc523
  • ihc523
  • 2014年04月19日 22:56
  • 2951

如何正确使用QThread

简述要实现一个线程很简单,写一个函数,绑定一些数据,如果有必要的话,可以使用 mutex 或者其他方法来保证和线程的安全交互。无论是 Win32、POSIX 或其他线程,工作原理都基本相同,并相当可...

c/c++易错知识点整理2(预处理,const,static,sizeof)(上)

预处理、const、static与sizeof 1.在#define宏中需要把参数小心地用括号括起来。因为宏只是简单的文本替换,如果不注意,很容易引起歧义。    #define SQR(x) (...

C++中三大修饰符 static const inline

C++中三个修饰符的深层剖析 static 是c++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因、作用谈起,全面分析static 修饰符的实质。 ...

C++笔记(常用关键字new、delete、static、const、friend,operator+-,内存结构)

1.new ,delete //C++ 通过new(delete)动态内存分配 //而C则是通过 malloc(free) Son* s1 = new Son(12); ...
  • ccj659
  • ccj659
  • 2016年09月05日 09:44
  • 232

C++知识点随笔(六):模板

一、函数模板C++中模板和重载的区别: 模板是除了类型全都相同的情况下可以使用;而重载是里面的功能也有不同时使用的。 下面看一个函数模板的使用实例:#include using namespace...

C++知识点随笔(七):成员函数指针、模拟虚函数列表

成员函数指针普通的全局函数指针定义:typedef void (*PFUN)();普通的函数指针可以指向返回值和参数类型都相同的全局函数,可是成员函数该怎么办呢?如果成员函数是static的,那么可以...

C++知识点随笔(二):继承、多态

一、继承继承是类之间的,对象之间没有什么关系,比如子类继承了父类的成员属性,并且子类的对象修改了这个成员属性,可是修改之后我们再去输出父类的成员属性发现并没有发生改变,原因是这两个对象本来就是两块空间...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++知识点随笔(三):static、const、friend、inline
举报原因:
原因补充:

(最多只允许输入30个字)