const char* arr = “123”;,
储存在常量区,只有一份拷贝;对于局部对象,常量存放在栈区,例如:void add(){const char crr[] = “123”;},
这里“123”本应储存在栈上,但编译器可能会做某些优化,将其放入常量区;对于全局对象,常量存放在全局/静态存储区;用const会比#define使用更少的空间,效率更高。这里有一个小例子:char* brr = "123"; char drr[] = "123";
前者字符串123存在常量区,不能通过brr去修改”123″的值;后者”123″保存在栈区,可以通过drr去修改。现在c++除了一些特定用法,推荐用const,inline,enum等替换宏——来自《effective c++》条款02const 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++;caaa类成员m_iv是const变量,必须放到初始化列表中进行初始化,不能进行赋值。对于静态常成员,与普通静态成员类似,推荐放到类外.cpp中初始化。aa只能调用const函数,如aa.getvalue(),不能调用非常成员函数aa.addvalueonetime()。对于这种const对象,又想修改成员,可以在成员声明加上mutable,这样const对象aa也可以修改m_ichangev,这种用法比较少。
const char* p1;char const *p2;char* const p3;const char* const p4;
对于初学者来说这大概是很难理解的一个知识点,怎么区分这四个呢?记住秘诀,直接从右向左读就一招制敌了。
p1是一个指针,指向char字符常量,表示p1所指对象内容不可以改,所指地址可以改。p2同p1,写法不同,两者等价。p3是一个常量,且是个指针,指向char字符,表示p3所指对象内容可以改,所指地址不可以改。p4是一个常量,且是个指针,指向char字符常量,表示p4所指对象内容不可以改,且所指地址也不可以改。相对来说p1,p2是最常用传参或者返回值的手段。float dvalue = 1.05f;const int& a = dvalue;const int itemp = dvalue;const int& a = itemp;因为常引用不能改变,这种情况下add的过去式编译器会创建一个临时变量来处理隐式转换,我们实际是对临时变量进行了常引用。
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).na水利水电学院me() << "pc type name: "整倍体 << typeid(pc).name() << std::endl;//pb[0] = 'a';//error, gmentation 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函数:
tem美国街头篮球plate <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;
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注www.887551.com的更多内容!
本文发布于:2023-04-04 00:26:27,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/79570b5a88c00cfa9ca2d6373d9a80ee.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:详解C++中的const和constexpr.doc
本文 PDF 下载地址:详解C++中的const和constexpr.pdf
留言与评论(共有 0 条评论) |