目录一.const常量与#define比较二.const修饰1.修饰普通变量,必须初始化2.修饰类变量和成员变量3.修饰成员函数4.修饰指针5.修饰引用三.const转换四.顶层co
const char* arr = “123”;,
储存在常量区,只有一份拷贝;对于局部对象,常量存放在栈区,例如:void add(){const char crr[] = “123”;},
这里“123”本应储存在栈上,但编译器可能会做某些优化,将其放入常量区;对于全局对象,常量存放在全局/静态存储区;用const会比#define使用更少的空间,效率更高。char* brr = "123"; char drr[] = "123";
前者字符串123存在常量区,不能通过brr去修改"123"的值;后者"123"保存在栈区,可以通过drr去修改。const int a = 10; 表示int对象a,是一个常量,不可以改变值,从编译器生成二进制角度看,生成的a存放在.rodata段,也就是只读(readonly)区域。不过并不绝对,有的时间统计优化等级开的高,也不取地址,可能会优化成立即数在.text段中。
class cAAA{
public:
cAAA(int a) : m_iV(a){}
const int GetValue() const {return m_iV;}
void AddValueOneTime(){m_iChangeV++;}
private:
const int m_iV;
public:
mutable int m_iChangeV;
static const int m_iStaticV;
};
static const int m_iStaticV = 1000;
const cAAA aa(100);
aa.GetValue();
aa.m_iChangeV++;
const char* p1;
char const *p2;
char* const p3;
const char* const p4;
对于初学者来说这大概是很难理解的一个知识点,怎么区分这四个呢?记住秘诀,直接从右向左读就一招制敌了。
float dValue = 1.05f;
const int& a = dValue;
const int iTemp = dValue;
const int& a = iTemp;
template <typename T>
struct RemoveConst{
typedef T Type;
};
template <typename T>
struct RemoveConst<const T>{
typedef T Type;
};
template <typename T>
using RCType = typename RemoveConst<T>::Type;
const char* pA = "sss";
char* pB = const_cast<char*>(pA);
auto pC = RCType<decltype(pA)>(pA);
std::cout << "type is the same: " << std::is_same<decltype(pB), decltype(pC)>::value << std::endl;
std::cout << "pB Type Name: " << typeid(pB).name() << "pc Type Name: " << typeid(pC).name() << std::endl;
//pB[0] = 'A';//error, Segmentation fault
const int iSize1 = sizeof(int);
const int iSize2 = GetSize();
iSize1是个常量,编译期的,但iSize2就不一定,它虽然不能改变,但要到GetSize()执行结束,才能知道具体值,这与常量一般在编译期就知道的思想不符,解决这个问题的方法就是改为:constexpr int iSize2 = GetSize();
这样要求GetSize()一定要能在编译期就算出值,下面几个例子中GetSizeError()就会编译失败。GetFibo函数,编译期就已经递归计算出值。
constexpr int GetSize(){
return sizeof(int) + sizeof(double);
}
constexpr int GetSizeError(){
return random();
}
constexpr int GetCalc(int N){
return N <= 1 ? 1 : N * GetCalc(N - 1);
}
const int iSize1 = sizeof(int);
constexpr int iSize2 = GetSize();
//constexpr int iSize3() = GetSizeError();
constexpr int iSize4 = GetCalc(10);
std::cout << iSize1 << " " << iSize2 << " " << iSize4 <<std::endl;
当然我们可以用模板写GetCalc函数:
template <int N>
struct TCalc{
static constexpr int iValue = N * TCalc<N-1>::iValue;
};
template <>
struct TCalc<1>{
static constexpr int iValue = 1;
};
std::cout << TCalc<10>::iValue << std::endl;
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!
--结束END--
本文标题: 详解C++中的const和constexpr
本文链接: https://www.lsjlt.com/news/159131.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0