#part1只读const的修改

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;

int main()
{
const int MAX_AGE = 90;
int* a = new int;
*a = 2;
std::cout<<*a<<std::endl;
return 0;
}

这里定义一个指针变量a,逆向引用这个变量就可以得到2

1
2

这里我想让a指向另一个东西,比如MAX_AGE

1
2
3
*a = 2;
a = &MAX_AGE;//cant do this
std::cout<<*a<<std::endl;

因为MAX_AGE是const常量,所以不可以这样写,但我们可以想想办法,绕开这个契约

1
2
3
*a = 2;
a = (int*)&MAX_AGE;//not good,but u can do this
std::cout<<*a<<std::endl;

强制转换MAX_AGE为int

part2指针const的玩法,常量指针与指针常量

1
2
3
4
5
6
7
8
9
int main()
{
const int MAX_AGE = 90;
const int* a = new int;//或者写int const* a = new int;
*a = 2;//error
a = (int*)&MAX_AGE;
std::cout<<*a<<std::endl;
return 0;
}

我们让指针变量a,也加上const,这意味着我们不能修改指针指向的内容

但是我们这么写*a = 2;会报错,因为我们试图修改常量指针a指向的内容了

但是当我们试图修改a本身的时候,我们并没有报任何错误

也就是说只能让指针指向的地址改变,而不能让它重新申请内存

这是const放在变量前的玩法

1
2
3
4
5
6
7
8
9
int main()
{
const int MAX_AGE = 90;
int* const a = new int;
*a = 2;
a = (int*)&MAX_AGE;//error
std::cout<<*a<<std::endl;
return 0;
}

这是第二种玩法,指针常量

const放在了*后面,然后让a指MAX_AGE这个操作报错了

因为我们不能够修改a本身了,但是可以修改a指向的内容

也就是说,可以让a重新申请内存,但是不能够改变a指向的地址

如果我前后都加const那么这两个操作都做不了了(很好理解吧)

const在类中的玩法

1
2
3
4
5
6
7
8
9
10
11
class Entity
{
private:
int m_X, m_Y;
public:
int GetX() const
{
m_X = 2;//error
return m_X;
}
};

如果我在类中函数里设置了const,那么我承诺了我在这个函数中不会对类中变量进行任何修改

只读不写

通常在getting中用,因为我们不会在其中修改变量

1
2
3
4
void SetX(int x)
{
m_X = x;
}

而在setting函数中,我们不能够加const,很明显我们是要获取数,加了const就没法修改了,这不符合我们初衷

结合我们常量指针和指针常量的玩法,可以写成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Entity
{
private:
int* m_X, m_Y;
public:
const int* const GetX() const
{
return m_X;//error
}
void SetX(int x)
{
m_X = x;
}
};

一行里写三个const,帅…

这玩意没啥实际用处,很明显我们不会这么用

需要指出一个问题,这里只有m_X变成了整型指针,m_Y依然是整型变量

要让m_Y也变成指针要这么写

1
int* m_X,*m_Y;//每个变量前都要加*

恢复成不是指针的原状

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Entity
{
private:
int m_Y, m_X;
public:
int GetX() const
{
return m_X;
}
void SetX(int x)
{
m_X = x;
}
};
//使用常量引用传递,这样可以不再复制一遍
//用引用没有指针本身和指针指向内容的区别了,因为引用就是内容
void PrintEntity(const Entity& e)
{
std::cout<<e.GetX()<<std::endl;
}

int main()
{
Entity e;
PrintEntity(e);
return 0;
}

这样我们可以在函数中调用GetX

如果我们移去GetX后的const,会报错,因为我们没法保证在PrintEntity中我们不会修改Entity类中变量

有时候出于调试原因,我们要在const中修改变量,可能用完就删

可以使用mutable,可修改的,这样我们可以在const中修改了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Entity
{
private:
int m_Y=0, m_X=0;
mutable int var;
public:
int GetX() const
{
var = 2;
return m_X;
}
void SetX(int x)
{
m_X = x;
}
};

这大概是const的基础玩法了,有新的知识,会再更新的

2023.6.29 23:39