c++ 11-14(三) 关键词(operator、sizeof 、static、static_assert)

operator

如下代码重载了&,使得address的类型为 int

struct AAA{
	int operator & (){
		return 10;
	}
};

void testOperator(){
	AAA a;
	auto address=&a;
	cout<<"address的类型:"<<typeid(address).name()<<endl;
}

 

但是operator在重载的时候有很多需要注意的地方

重载“=”

struct AAA {
	~AAA() { delete m_value;}
	AAA() : m_value(new int()) {}
	AAA(const AAA& rhs) : m_value(new int(*(rhs.m_value))) {}
	AAA& operator = (const AAA& rhs) {
		*m_value = *(rhs.m_value);
		return *this;
	}

	private:
		int* m_value;
};

void testOperator(){
    AAA a;
    AAA b=a;  //调用拷贝构造函数
    b=a;      //调用拷贝赋值函数
    //cpp中默认的拷贝赋值函数是按值拷贝,也就是说,执行完这句,a和b指向同一个内存
    //此时如果释放b的内存,则a和b所指的内存就都被释放掉了
    //如果b释放过内存之后,a又一次对该块内存进行释放,就会出现问题
}

此时,我们需要重载“=”,防止浅拷贝

 

 

 

reinterpret_cast

void testReinter() {
	int a = 1;
	auto p = reinterpret_cast<char*>(&a); //将&a强转成char*的指针

	//检测大小端的另一种方式
	if(p[0] == 1) std::cout << "the system is little endian\n";
	else std::cout << "the system is big endian\n";
	// reinterpret_cast
	// static_cast
	// const_cast
	// dynamic_cast
	// c like cast——c类型的cast很强大,除了dynamic_cast之外,其余三种cast都是通过c like cast
	//来进行转换的。比如下面的例子:
	auto pp = (char*)(&a);  //没有问题
	const AAA bb;
	auto pbb = const_cast<AAA*>(&bb); //正确
	auto cbb = (AAA*)(&bb);  //正确
	int c = 100;
	auto cc = static_cast<char>(c);   //正确
	auto ccc = (char)c;
	//C++中设计出这么多的cast,是为了让使用者明确各个cast的用法。各种cast是不能相互转换的
}

 

 

 

sizeof 

c++11之前

class Empty {};
class Base { int a; };
class Derived : Base { int b; };
class Bit { unsigned bit: 1; };
// c++11 before
void testSizeof() {
	Empty e;
	Derived d;
	Base& b = d;
	Bit bit;
	std::cout << sizeof e << std::endl;          //  1
	std::cout << sizeof(Empty) << std::endl;     //  1
	std::cout << sizeof(&e) << std::endl;        //  4(32位),8(64位)
	std::cout << sizeof(Derived) << std::endl;   //  8
	//std::cout << sizeof(void) << std::endl;    //会报错,因为void没有大小
	//std::cout << sizeof(int[]) << std::endl;   //会报错,对于非明确的类型会报错,因为数组大小未知
	//std::cout << sizeof(bit.bit) << std::endl; //会报错,因为大小不足一个字节
}

2019.6.4补充

感谢大佬指出问题

 

c++11之后(以后补)

 

 

 

static

 

1、static在外部文件中的语法

//globalA是在预编译的时候就已经分配好了内存地址空间了
//两个文件都定义了static全局变量的话,生成顺序是不确定的,因此最好不要这么用static
static int globalA = 0; //声明了文件范围内全局可见的globalA。
void printInfo() {
	//函数内static变量。只有当函数第一次被调用时,才会给localStatic分配内存空间。
	//第二次调用的时候就继续使用之前分配的内存空间
	//这种static的使用方式也是不推荐的:
	//比如:多线程的情况下容易出现bug.比如两个线程都调用了这个函数,两个线程可能两边打印出来的结果都是2
	static int localStatic = 0;  
	++localStatic;
	std::cout << S::s << " " << globalA << " " << localStatic << std::endl;
}

 

2、static在类中的语法

struct S {
	static int s;
};
// sizeof(S) == 1  因为s只是归属于S,但是他是static,所以s不是S的成员。因此S的大小和空类是一样的,因此是1

int S::s = 10; //初始化

struct Foo;
struct SS {
	static int a[];
	static Foo foo;
	static SS ss;
};

//实例化
int SS::a[10];
struct Foo {};
Foo SS::foo;
SS SS::ss;

 

 

 

 

static_assert(c++11)

static_assert能做的事情,assert也能做。但是assert有一定的问题

  • 1、assert是一个宏,在debug版本和release版本是不一致的
  • 2、assert在运行时期才会发现问题,而static_assert在编译时期就能发现问题,相当于缩短了开发的迭代周期

 

但是static_assert里面跑的东西只有在编译期才会发生作用,因此下面代码中发的判断语句要用assert
因为a==b是在运行期进行判断的,而不是编译期

void testStaticAssert() {
	int a = 4;
	int b = 5;
	//static_assert能做的事情,assert也能做。但是assert有一定的问题
	//1、assert是一个宏,在debug版本和release版本是不一致的
	//2、assert在运行时期才会发现问题,而static_assert在编译时期就能发现问题,相当于缩短了开发的迭代周期
	//但是static_assert里面跑的东西只有在编译期才会发生作用,因此下面的判断语句要用assert
	//因为a==b是在运行期进行判断的,而不是编译期
	assert((a == b) &&  "only work for int for 32 bit");  
}

template<typename T>
void func(T t) {
	//编译时期如果不满足编译条件,就会停止编译,并输出 only for alignof 4
	static_assert(alignof(T) == 4, "only for alignof 4"); 
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值