[C++]——指针常量 & 常量指针 &引用作用域

一、指针常量 & 常量指针

(1)、有以下定义,说明哪些量可以改变哪些不可以改变

 const char *p;                    *P不改变,P可以改变

 const (char *) p;                 *P不改变,P可以改变

char *const p;                     报错

const char* const p;            P和*P不改变

 char const *p;                    *P不能被改变,P可以改变

(char *) const p;                  报错

 char const* const p;           *P和P不改变

  1. const char *p:指向字符常量的指针,可更改指针以修改 p 自身以指向不同的数据(地址),不能通过 p 修改它所指向的内容。
  2. const (char *) p:指向字符常量的指针,可更改指针本身,但不能更改所指向的字符内容。
  3. char *const p:报错,通常情况下const放在*之前,而并非放在指针变量p之后。
  4. const char* const p:指向字符常量的常量指针,不可更改指针以修改 p 自身以指向不同的数据(地址),不能通过 p 修改它所指向的内容。
  5. char const *p;:指向字符常量的指针,类似于第一种情况。也就是说,可更改指针以修改 p 自身以指向不同的数据(地址),但不能更改p 自身所指向的字符内容。
  6. (char *) const p:报错,通常情况下const放在*之前,而并非放在指针变量P之后。
  7. char const* const p:指向字符常量的常量指针,既不能通过p指针更改指向地址,也不能改变p所指向的字符内容。此处const修饰符的顺序可以稍作修改,如const (char const*) p。

 二、C++中":"和"::"区别

(1)、单引号:

1.继承

class 派生类名 :继承方式 基类名


#include <iostream>
using namespace std;
 
class BaseClass
    {
    public :
     BaseClass();// 构造函数
    ~BaseClass();// 析构函数
    }
    
class SubClass:public BaseClass()
    {
    }

  2.初始化参数

初始化类的成员两种方式:

一、是使用初始化列表

二、是在构造函数体内进行赋值操作

2.1初始化参数原因

原因:主要是出于性能问题,对于内置数据类型:如int, double等,使用初始化列表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表。因为使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,非常高效
所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表

2.2成员变量顺序

成员是按照他们在类中出现的顺序进行初始化的,而不是按照他们在初始化列表出现的顺序初始化的。

3. 位域

该种形式出现于结构体或共用体的定义中,是位域定义的标准形式。

struct BaseClass
{
	type var_name : m;
};
  1. 含义为,在结构体BaseClass汇总,成员变量var_name占用空间为m位。
  2. m为正整数,其值必须小于type类型占用的位数。比如type如果是int,占4字节32位,那么m必须是1~31之间的整数。
  3. 对于位域类型的成员,在赋值时如果实际值超过n位所能表达的范围,那么超出部分将会被截掉,只保存低位值。例:int var:4,本身只有4位的空间,如果赋值var = 20, 由于20的二进制值为10100,实际为五位,这时var实际被赋值的就是低四位,0100,即4。

(2)、双引号::

1. 类作用域,用来标明类的变量、函数

作用域符号::的前面一般是类名称,后面一般是该类的成员名称,C++为例避免不同的类有名称相同的成员而采用作用域的方式进行区分

	Human::SetName(char* name);

2. 命名空间作用域,用来注明所使用的类、函数属于哪一个命名空间

	std::cout << "Hello World" << std::endl;

3. 全局作用域,用来区分局部、全局

全局作用域符号:当全局变量在局部函数中与其中某个变量重名,那么就可以用::来区分如:

char base;    //全局变量
void Init()
{
      char base;    //局部变量
      char(局部变量) = char(局部变量) *char(局部变量) ; 
     ::char(全局变量) =::char(全局变量) *char(局部变量);
}

一般写了一个全局函数或者想要调用一个全局函数,却发现IDE或者Editor找不到该函数,原因是因为局部函数与想要调用的全局函数名字重合,然后找了很久也找不到原因,甚至放弃解决的。其实原因就是因为 【局部变量/函数】 与 【全局变量/函数】 的名字相同,IDE无法区分,这时候加上 :: 就可以调用到全局函数,访问到全局变量。

示例:

.h文件下打开、关闭函数api接口

//.h文件下的全局函数
File* open (const char *p, int flag)

//.h文件下的全局函数
extern int close (int fd);

由于每次找api是一件非常浪费加载时间,而且是没多大意义的事情,我现在要将这个函数封装成个人串口库base.cpp

//Base.h
class Base
{
public:
    bool open();
    void close();
}

注意以下的cpp文件,如果没有 :: 则会报错误,因为Base库中有函数open和close,跟全局函数open和close名字相同,如果不做全局与局部的区分,则无法调用到全局函数

// Base.cpp
bool  Base::open()
{
	if( ::open(portname,O_RDWR|O_NOCTTY|O_NONBLOCK) != -1 )
		return true;
	else
		return false;
}
void  Base::close()
{
	::close(fd);
}

三、总结命名空间使用时的方式和注意事项

  1. 多个空间变量冲突时,要使用域限定符,来标识一个命名空间;
  2. 本地群居和局部冲突,本地全局变量使用::变量名的引用,因为本地全局变量保存在匿名空间内;
  3. 在命名空间内定义函数,需要给函数加上域限定符和命名空间
  4. 嵌套命名空间,需要一级一级引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值