C++11 note-1引用指针和const

本文深入探讨了C++中的引用与指针的概念、使用方式及注意事项,包括引用的初始化、绑定、不可更改性,指针的赋值、指向对象与内存地址的原理,以及如何在代码中正确地使用它们。


Conference pointer and const

CPPP P45-60

引用-取别名(同等异名)

 引用,也就是为了给变量取别名,因此,他引用的是变量名、表达式而不是常量;同时,引用必须要初始化,一旦引用完成,引用将和它的初始值对象一直绑定在一起,不能将引用重新绑定在另一个对象上;不能定义引用的引用。但是可以有一例外:

                      const &p = 10 ; 是合法的

 需要特别理解注意:引用不是对象。所以没有引用的引用,因为,引用无法再引用一个已经引用了的变量(它此时不是对象了)。

指针-指向内存地址(指向对象)

 指针,也就是将用一变量直接指向一内存中的地址,它必须要赋初始值(C++中所有的定义的变量都是要赋初始值的),空时,可以指向ullptr;指针及其指向的内存地址中的变量可以改变值;无返回类型时,可以定义为void*

指针其实也是一种类型,所以可以叫为“指针变量”,它是一对象,所以有指向指针的指针,它的意义是内存的多重指向。

 还有,如果定义了指针

                         int  *P = q ;

那么在后面,*p其实就是代表指向q的内存地址的值,也就是等价于q(在取值上)*是解引用符号;P其实就是指针(变量)。还有如果int *j = nullptr; ,那么,w = j ; 语句就是将w指针与j指针等起来,所以w 就是p 了(在指针指向的内存地址上,也就是q的值上)。

  补充:关于指针的值的问题

  1. 指向一个对象 *p = q;

  2. 指向紧邻对象所占空间的下一个位置 在链表中

  3. 空指针,意味着指针没有指向任何对象 *p = nullptr;

  4. 无效指针,也就是以上之外 - 没遇到过? 也就是说指针的错误用法吧,也许

Const限定符-固定死值(常量引用)

引用就是将一个值、变量、表达式“固化”到一个变量、引用、指针上。注意,它必须要初始化。与引用和指针不同的是,一旦“固化”了,那么,不可以将它再改值。同理,const的引用固化引用,不可改,但是有一特例:

                        Const int &p = 10;     //OK,因为p是一个“常量引用”

                         Int&p = 10 ;          //ERROR,因为引用类型的初始值必须要是一个对象

  同时,注意在const中对引用、指针的两两之间的同一操作关系,就好比如double变量从语法上来讲必须与同是double类型的变量来进行赋值、代数运算等等。

其他:顶层const(最死const  constexpt和常量表达式(常量const

  顶层const,也就是不可改的固定死的const,而底层const,是可以改变的,一般的底层的底层const 是跟指针一起使用的。在多重的const限定符、引用和指针中,看除基本变量类型外的最左边的修饰符,其他的是对这个(基本类型+第一修饰符的)变量的多层修饰,也就是说,从右向左读变量的修饰符即可。例如:

                         Inti = 0;

                         Int*const pi = &I ;     //顶层const,不能改变p1的值

                         Constint ci = 42;      //顶层const,不能改变ci的值

                         Cosntint *p2 = &c1 ;      //底层const ,可以改变p2的值

                         Constint *const p3 = p2 ; 

                                  //靠左的const是底层const ,靠右的const的是顶层const

                         Cosntint &r = ci;   //用于声明引用的const都是底层const

  常量表达式,也就是,“常量”的“表达式”,即是const + 基本数据类型,必须初始化!!!!。只要变量是一个常来那个表达式,那么就应该声明为constexpr类型,但是应该是简单的字面值类型(算数类型、引用和指针),而类、IO库、string库等都不是。在constexpr与指针中,初始值只能够是nullptr或者是0,同时,在constexpr中,限定的只是对指针有效,而对指针所指的对象无关,例如:

                         Constint *p =  nullptr ;   //p是一个指向整型常量的指针

                         Constexprint *q = nullptr;   //q是一个指向整数的常量指针

也就是说,p是一个“指向常量的指针”,而q是一个“常量指针”,constexpr把它所定义的对象置为顶层const

 

 

附:以上相关的见下代码:

#include<iostream>

int main()

{

    //pointer and constant

    int i = 10;

    int *p = &i;

    i = 20;

    std::cout << " i : " << i << std::endl;

    std::cout << " *p : " << *p << std::endl;

    *p = 30;

    std::cout << " i: " << i << std::endl;

    std::cout << " *p " << *p << std::endl;

    std::cout << "----------------------------------------------------------------" << std::endl;

    //reference and constant

    int j = 1;

    int &q = j;

    j = 2;

    std::cout << "j :" << j << std::endl;

    std::cout << "q :" << q << std::endl;

    q = 3;

    std::cout << "j :" << j << std::endl;

    std::cout << "q :" << q << std::endl;

    std::cout << "-----------------------------------------------------------------" << std::endl;

    // const and initialization

    int c = 9;

    const int c1 = c;

    int const c2 = c;

    std::cout << "c1 :" << c1 << std::endl;

    std::cout << "c2 :" << c2 << std::endl;

    std::cout << "c :" << c << std::endl;

    //it's wrong c1 = 8;

    //it's wrong c2 = 7;

    c = 6;

    std::cout << "c1 :" << c1 << std::endl;

    std::cout << "c2 :" << c2 << std::endl;

    std::cout << "c :" << c << std::endl;

    std::cout << "-----------------------------------------------------------------" << std::endl;

    //const and reference

    int r = 55;

    const int &r1 = r;

    std::cout << " r: " << r << std::endl;

    std::cout << " r1: " << r1 << std::endl;

    r = 44;

    //it's wrong r1 = 33;

    std::cout << " r: " << r << std::endl;

    std::cout << " r1: " << r1 << std::endl;

    std::cout << "----------------------------------------------------------------" << std::endl;

    //const and pointer

    const double pi = 3.14;

    //it's wrong double *ptr =&pi;  //because ptr is not a consttype

    const double *ptr = &pi;

    std::cout << "pi: " << pi << std::endl;

    std::cout << "*ptr: " << *ptr << std::endl;

    //it's wrong *ptr = 42;

    std::cout << "one more :" << std::endl;

    int errNumb = 0;

    int *const curErr = &errNumb;

    const double pp = 3.1415926;

    const double *const pip = &pp;

    std::cout << "errNum: " << errNumb << std::endl;

    std::cout << "*curErr: " << *curErr << std::endl;

    std::cout << "pp: " << pp << std::endl;

    std::cout << "*pip: " << *pip << std::endl;

    errNumb = 99;

    //it's wrong pp = 88; because pp is aconst and can't be changed

    std::cout << "errNum: " << errNumb << std::endl;

    std::cout << "*curErr: " << *curErr << std::endl;

    std::cout << "pp: " << pp << std::endl;

    std::cout << "*pip: " << *pip << std::endl;

    std::cout << "---------------------------------------------" << std::endl;

    return 0;

}

a.cpp:9:49: error: non-member function ‘Complex operator-(Complex&)’ cannot have cv-qualifier 9 | friend Complex operator-( Complex &c3 ) const;//重载双目运算符'-' | ^~~~~ a.cpp:25:9: error: no declaration matches ‘Complex Complex::operator-=(Complex&) const’ 25 | Complex Complex::operator-=(Complex &c2)const | ^~~~~~~ a.cpp:8:17: note: candidate is: ‘Complex Complex::operator-=(Complex&)’ 8 | Complex operator-=( Complex &c2 ); //重载双目运算符'-=' | ^~~~~~~~ a.cpp:3:7: note: ‘class Complex’ defined here 3 | class Complex | ^~~~~~~ a.cpp:31:9: error: no declaration matches ‘Complex Complex::operator-(Complex&) const’ 31 | Complex Complex::operator-(Complex &c3)const | ^~~~~~~ a.cpp:31:9: note: no functions named ‘Complex Complex::operator-(Complex&) const’ a.cpp:3:7: note: ‘class Complex’ defined here 3 | class Complex | ^~~~~~~ a.cpp: In function ‘int main()’: a.cpp:44:12: error: no match for ‘operator-’ (operand types are ‘Complex’ and ‘Complex’) 44 | c3 = c1-c2; | ~~^~~ | | | | | Complex | Complex In file included from /usr/include/c++/11/bits/stl_algobase.h:67, from /usr/include/c++/11/bits/char_traits.h:39, from /usr/include/c++/11/ios:40, from /usr/include/c++/11/ostream:38, from /usr/include/c++/11/iostream:39, from a.cpp:1: /usr/include/c++/11/bits/stl_iterator.h:577:5: note: candidate: ‘template<class _IteratorL, class _IteratorR> constexpr decltype ((__y.base() - __x.base())) std::operator-(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)’ 577 | operator-(const reverse_iterator<_IteratorL>& __x, | ^~~~~~~~ /usr/include/c++/11/bits/stl_iterator.h:577:5: note: template argument deduction/substitution failed: a.cpp:44:13: note: ‘Complex’ is not derived from ‘const std::reverse_iterator<_IteratorL>’ 44 | c3 = c1-c2; | ^~ In file included from /usr/include/c++/11/bits/stl_algobase.h:67, from /usr/include/c++/11/bits/char_traits.h:39, from /usr/include/c++/11/ios:40, from /usr/include/c++/11/ostream:38, from /usr/include/c++/11/iostream:39, from a.cpp:1: /usr/include/c++/11/bits/stl_iterator.h:1693:5: note: candidate: ‘template<class _IteratorL, class _IteratorR> constexpr decltype ((__x.base() - __y.base())) std::operator-(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorR>&)’ 1693 | operator-(const move_iterator<_IteratorL>& __x, | ^~~~~~~~ /usr/include/c++/11/bits/stl_iterator.h:1693:5: note: template argument deduction/substitution failed: a.cpp:44:13: note: ‘Complex’ is not derived from ‘const std::move_iterator<_IteratorL>’ 44 | c3 = c1-c2; | ^~ a.cpp:9:24: note: candidate: ‘Complex operator-(Complex&)’ 9 | friend Complex operator-( Complex &c3 ) const;//重载双目运算符'-' | ^~~~~~~~ a.cpp:9:24: note: candidate expects 1 argument, 2 provided 确
05-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值