effective c++尽量少做转型动作(1)

时间:2021-03-24 05:35:20

为啥要分两次写呢,因为这篇实在是太长了,因为畏惧他的长度,所以这几天竟然一直拖着没有写effective c++的读书笔记,导致也没有往后面太看。。。所以,以后如果文章太长了,不要惧怕,分开写就好了,还是重在坚持

看这章内容,一下子就被其中的const_cast(expression)表达式所吸引了,c++就是作死小能手,想怎么耍就怎么耍!它可以将对象的常量性转除!!

然后马上查了一下c++ reference

#include <iostream>
using namespace std;
struct type {
type() :i(3) {}
void m1(int v) const {
// this->i = v; // compile error: this is a pointer to const
//常量函数不能修改对象
//所以常量对象仅能调用常量对象

const_cast<type*>(this)->i = v; // OK as long as the type object isn't const
//将这个对象的常量性解除
}
int i;
};

int main()
{
int i = 3; // i is not declared const
const int& cref_i = i;
const_cast<int&>(cref_i) = 4; // OK: modifies i
std::cout << "i = " << i << '\n';

type t;
//无实参的构造函数,将常量赋值为3
// note, if this is const type t;, then t.m1(4); is UB
t.m1(4);
std::cout << "type::i = " << t.i << '\n';

const int j = 3; // j is declared const
int* pj = const_cast<int*>(&j);
*pj = 4; // undefined behavior!
cout << j << " j " << endl;
cout << *pj << " pj " << endl;
//这里j != *pj 一会解释可能的原因



void (type::*mfp)(int) const = &type::m1; /// pointer to member function
/// const_cast<void(type::*)(int)>(mfp);
/// compiler error: const_cast does not work on function pointers
//const_cast只能作用于对象,而不能使函数指针
}

这是上面的注释,我又自己加了一些自己的实验和理解

然后是stack overflow的一个例子

void func(const char *param, size_t sz, bool modify)
{
if(modify)
strncpy(const_cast<char *>(param), sz, "new string");
printf("param: %s\n", param);
}

...

char buffer[16];
const char *unmodifiable = "string constant";
func(buffer, sizeof(buffer), true); // OK
func(unmodifiable, strlen(unmodifiable), false); // OK
func(unmodifiable, strlen(unmodifiable), true); // UNDEFINED BEHAVIOR
//stack overflow 论坛也提到了,用指针修改一个常量,行为是未定义的!

下面是CMbug博客的一些引用
C++编译器对const常量的处理:
当碰见常量声明时在符号表中放入常量;
编译过程中若发现使用常量则直接以符号表中的值替换;
编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间,否则,不分配存储空间;
C++中,const常量可能会被分配存储空间:
当const常量为全局,并且需要在其它文件中使用时
当使用&操作符取const常量的地址时

注意:
  C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值。
effective c++尽量少做转型动作(1)

C语言中的const常量:
C语言中const常量是只读变量,有自己的存储空间;
C语言中const常量的值是可改的,因此我有时也称它为“常变量”;


虽然不好,但是我就是想改变常量,我发现在struct里面的常量是可以修改的!:

#include <iostream>
using namespace std;
struct ConstTry
{
int a = 1;
const int b = 2;
}c;
int main()
{
cout << c.a << " c.a c.b " << c.b << endl;
int *p0 = &(c.a);
cout << *p0 << " p " << endl;
p0++;
cout << *p0 << " p " << endl;
*p0 = 5;
cout << *p0 << " p " << endl;
cout << c.a << " c.a c.b " << c.b << endl;
}

effective c++尽量少做转型动作(1)
但是这种行为往往是未定义的,只是我的编译器是这个结果,其他编译器就不一定了。所以,常量还是不要改。