c++引用的误区

作者: littlersmall | 来源:发表于2016-01-21 13:16 被阅读192次

c++的引用一直都是一个很重要的概念,而且使用的场合很多,比如通过引用减少不必要的临时对象拷贝,或者通过传递引用作为函数的返回值。
int get_stm(int& stm); 这里的stm就是需要get的值,而函数本身的返回值则作为错误判断的依据,例如返回0则正确,非0值则表示错误等。
前面说的这些都是很常规的用法,也不存在什么误区。最近在设计一个内存模型时有这样的一个需求:

class Table
{
    int table_id;
    
    Row* row_array;
};

class Row
{
    int table_id;
    int column_num;
    ...
    ...
}

在这两个类中,第一个类描述一个数据库的表,而第二个类则描述了一个表中的某一行的信息,这里面存在着数据的冗余,table_id。因为一张表的每一行的table_id都是相同的,而如果想要在每一行中省略掉table_id的内存开销,有几种方式。
1 将table_id设定为static
2 将table_id改为一个引用
先说第一种方式,看似可以解决问题,但实际中,由于涉及到多张表,每张表的table_id必定不同,而如果将Row的table_id设定为static,就会出现每张表的每行数据的table_id是相同的,这样显然是错误的。如果改为一个static数组,似乎可以解决问题,但又过于复杂。
第二种方式,利用引用,代码大致是这样的:

class Row
{
    const int& table_id;
    ...
    public:
    Row(const int& t_id) : table_id(t_id)
    {}
};

看上去很完美,既节省空间,而且关系清晰,不会出现问题。
在这种方式中,我们做了一个假定:c++中的引用不会占用额外的内存。
从引用的原理上看确实是这样,它是一个别名,作为一个并不存在的东西指向实际的变量...
但实际上呢?

如果你在gcc中测试这样的一段代码:

class A
{
    int& a;
    int& b;
    int& c;
    int& d;
    
    int e;
};

int main()
{
    cout << sizeof(A) << endl;
    
    return 0;
}

就会发现输出的结果是36 !!!! (64位环境)
36 = 32 + 4; 也就是4个指针和一个int。
换句话说,引用并不像它看上去的那么美好,其实不过是一层指针的封装.....
一直以来都觉得引用是一种类似作用域的扩展,也就是把变量原本的作用域,扩展到了需要的地方,而实现的方式,大致是在链接的时候,将所引用的符号变量替换为实际的地址.....虽然也听过引用的实现和指针类似,但是还一直觉得是原理类似,而不是实现。
但现实真的很残酷。
在gcc,clang,vc等等编译器中,都是使用一个简单的指针替换引用,大概类似这样:

int b;
int& c = b;
c = 3;
//实际实现时
int b;
int* c = &b;
*c = 3;

注:就算是全局空间的引用,也需要占用一个指针的内存,编译器并没有对其做任何优化。

深究其原因,是因为c++标准中并没有定义引用该如何实现,而大家就不约而同的选择了相对简单的实现方式....
结论:
1 引用并不会节省内存,开销相当于一个指针
2 所有使用引用的地方都可以用指针替代,反之则不然(无法实现空引用)
(原文时间2014-1-21)

相关文章

  • c++引用的误区

    c++的引用一直都是一个很重要的概念,而且使用的场合很多,比如通过引用减少不必要的临时对象拷贝,或者通过传递引用作...

  • c++学习文档-更新于2020年12月05日

    c++学习文档汇总 [TOC] c++ primer部分 c++学习笔记 引用(左值引用) int &ref...

  • C++基础

    C++ 值传递、指针传递、引用传递详解C++中引用传递与指针传递区别 引用传递和指针传递的区别 引用的规则:(1)...

  • [C++之旅] 4 C++的引用

    [C++之旅] 4 C++的引用 基本数据的引用 apple_a为apples的引用,修改apple_a等同于修改...

  • C++ 引用传递的学习

    C++ 引用与引用作为函数的参数C++函数的三种传递方式为:值传递、指针传递和引用传递 C++ 上课习题 刘月林2...

  • C++知识点

    C++基本方法: C++ memcpy C++基本特性: C++引用(vs指针) C++指针 C++封装: 将...

  • C++入门系列博客三 引用和指针

    C++ 引用和指针 作者:AceTan,转载请标明出处! 引用和指针对于C++来说很重要,是学习C++绕不过去的一...

  • C++右值引用

    C++ 右值引用译

  • 在某些情况下,实参与引用参数不匹配,C++将生成临时变量

    如果实参与引用参数不匹配,C++将生成临时变量。当前,仅当参数为const引用时,C++才允许这样做。如果引用参数...

  • C++特性之引用 (Boolan)

    C++特性之引用 (Boolan) 本章内容:1 引用的不同用例1.1 引用变量1.2 引用数据成员1.3 引用参...

网友评论

本文标题:c++引用的误区

本文链接:https://www.haomeiwen.com/subject/komlkttx.html