delete[]的析构顺序
先说一个小发现,在delete []的时候,是按照与构造顺序相反的顺序来析构的!(原来的构造顺序指的是,new []的时候,是按照下标顺序构造的)
#include <iostream>
using namespace std;
class Log
{
public:
void setId(int id) {
this->id = id;
}
~Log() {
cout << "Destruct " << id << endl;
}
private:
int id;
};
int main() {
Log* logs = new Log[4];
for (int i = 0; i < 4; ++i)
logs[i].setId(i);
delete [] logs;
return 0;
}
上面代码的输出结果为:
Destruct 3
Destruct 2
Destruct 1
Destruct 0
引用变量的大小
据说编译器内部是通过“常量指针”来实现引用的,首先从它的大小来看一下:
#include <iostream>
using namespace std;
class Log
{
public:
void setId(int id) {
this->id = id;
}
~Log() {
cout << "Destruct " << id << endl;
}
private:
int id;
};
struct Wrapper
{
Log& ref;
Wrapper(Log log)
: ref(log) {}
};
int main() {
Log log;
Wrapper w(log);
cout << sizeof(w) << ' ' << sizeof(log) << endl;
return 0;
}
输出结果是:8 4
8是一个指针的大小!ps,不能直接通过sizeof(ref)来判断,因为这样会输出4 4
,计算的是ref所引用的对象的大小。
常量指针 VS 指针常量
下一个主题需要区分指针(类型的)常量和(指向)常量(的)指针,相信看了左边括号里的注释,应该都清楚了吧?
还不清楚,只能po我自己的私藏笔记了:
常量指针,顾名思义,就是指向一个常量的指针,比如:
const int id = 555;
const int* p1 = &id;
int const* p2 = &id;
*p1 = 233; // 错误!不允许通过指针修改变量的值,因为指向的是常量
int hello = 666;
p1 = p2 = &hello; // 可以给指针重新赋值,指针本身不是常量
它的特点是,不能通过指针去修改所指向变量的值,常用于函数传参时声明变量内容不允许被修改(当然也可以用常引用)。
xx常量指的是这个变量是一个常量,不能修改其值,所以,“指针常量”指的就是这样的形式:
int id = 233, id2 = 555;
int* const p = &id;
id = 666;
p = &id2;// 错误!p是一个常量,不允许修改它的值
p = &id;// 错误!这样也不行,不要以为p的值等于&id就可以给它赋值,哼╭(╯^╰)╮
你可以修改原始变量的内容(只要它不是const修饰的),但是不能改变指针的值,也就是说,这个指针就只能被指定为指向这个变量了!
据说,编译器内部用常量指针来实现引用!(只是传言而已)
用指针常量来模拟引用!
直接po代码,代码清晰得,都不用解释的^_^
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <string>
using namespace std;
class Log
{
public:
Log(int n)
: id(n) {}
Log& operator = (const Log& rhs) {
id = rhs.id;
return *this;
}
void display() const {
cout << "Log " << id << endl;
}
private:
int id;
};
template<typename T>
class Reference
{
private:
/* 使用“指针常量”来模拟引用的行为:
1) 只能绑定一个变量;
2)必须在初始化才能使用;
3)后续的所有赋值都是改变所绑定的变量的值。
至于为什么是指针常量,是因为要求,这个指针不能改为指向别的变量!
*/
T* const pointer;
public:
Reference(T& object)
: pointer(&object) {}
T& operator = (T& object) {
return *pointer = object;
}
};
int main() {
Log test(233);
test.display();
Reference<Log> ref(test);
Log test2(666);
ref = test2; // 通过引用改变所绑定的值
test.display();
return 0;
}
输出结果是:
Log 233
Log 666
未完待续
更新于2016-08-18 15:57
jacket
于至善园4号