
this 关键字是一个指针,指向的是方法指向的当前的类的实例。当我们定义类的一个non-static的方法时,必须首先有一个对象,然后才能调用这个方法。譬如下面的代码:
#include <iostream>
class Entity {
public:
int x, y;
Entity(int x, int y)
{
}
};
int main() {
std::cin.get();
}
这是如果想在构造函数中赋值,可以看到成员变量和参数是同名的,这时就可以使用this来进行区分:【当然,此时也可以使用初始化列表来进行赋值】
class Entity {
public:
int x, y;
Entity(int x, int y)
{
this->x = x;
this->y = y;
}
};
int main() {
std::cin.get();
}
注意,this实际上是个指针,
Entity * e = this;
所以这里需要使用->,或者使用(*this).x。
this还有一个用处是在类函数中调用外部函数,而又需要将自己作为参数进行传递。
#include <iostream>
void PrintEntity(Entity* e);
class Entity {
public:
int x, y;
Entity(int x, int y)
{
this->x = x;
this->y = y;
PrintEntity(this);
}
};
void PrintEntity(Entity* e) {
}
int main() {
std::cin.get();
}
比较浅显,感觉this比较神秘
下面是stack和heap。之前一直在说stack的作用域问题,下面看一个代码的例子:
#include <iostream>
class Entity{
public:
Entity()
{
std::cout << "created Entity!" << std::endl;
}
~Entity()
{
std::cout << "destroyed Entity!" << std::endl;
}
};
int main() {
{
Entity e;
}
std::cin.get();
}
运行结果如下:

还可以断点调试一下,效果更明显。
如果将代码改成
Entity * e = new Entity();
下面是一个错误的例子:
int * CreateArray(){
int array[50];
return array;
}
上面的代码,一旦调用,栈上的空间也被清除了,因此不可能返回一个数组;
正确的做法是:1. 分配在堆上
int * CreateArray(){
int array = new int[50];
return array;
}
或者2. 先在调用的函数中创建好空间,然后在CreateArray中进行操作:
void CreateArray( int * array){
//fill the array
}
int main(){
int array[50];
CreateArray(array);
}
下面的代码实现的是在栈上分配一个指针,然后当scope结束的时候,自动删除,也成为scoped pointer。
#include <iostream>
class Entity{
public:
Entity()
{
std::cout << "created Entity!" << std::endl;
}
~Entity()
{
std::cout << "destroyed Entity!" << std::endl;
}
};
class ScopedPtr {
private:
Entity* m_Ptr;
public:
ScopedPtr(Entity * ptr)
: m_Ptr(ptr)
{
}
~ScopedPtr()
{
delete m_Ptr;
}
};
int main() {
{
ScopedPtr * e = &ScopedPtr(new Entity());
}
std::cin.get();
}
不明白有什么样的应用场景~~Cherno讲了一个timer的例子,什么时候进入,什么时候退出;以及locks,还是不是很清楚......
smart pointer:是一种巧妙的C++技术;使得可以避免在使用new的时候一定要使用delete。或者,在C++编程的时候根本不用调用new 和 delete。smart pointer是一种wrapper,包装了基本的指针;当调用smart pointer的时候,会自动调用new,而在某个阶段,会自动调用delete。
第一个例子是unique pointer。unique pointer是一种scoped pointer,充分利用了栈自动销毁的特性。Unique Pointer不能复制,因为如果有两个Unique pointer指向同一块内存空间,当一个pointer删除的时候,它会释放那块空间,那么另一个指针指向的就是无效空间了。
#include <iostream>
#include <memory>
class Entity{
public:
Entity()
{
std::cout << "created Entity!" << std::endl;
}
~Entity()
{
std::cout << "destroyed Entity!" << std::endl;
}
};
int main() {
{
std::unique_ptr<Entity> entity(new Entity());
}
std::cin.get();
}
貌似unique_ptr是一个模板,这种用法。另外,unique_ptr有explicit关键字,所以必须显式调用构造函数。
如果想要进行复制,会报错。
std::unique_ptr<Entity> e1 = entity;
因为复制赋值的操作符 = 被设计成:
unique_ptr(const _Myt&) = delete;
Myt& operator=(const _Myt&) = delete;
防止自掘坟墓,英文中有类似的表达——digging yourself into a grave.
如果想要复制,那么有shared pointer。shared pointer要更复杂一点,因为它需要悄悄完成更多的工作,基本而言,使用了reference counting【类似于软链接】。也就是必须的自己记下来到底有几个指针指向这块内存,只有当count为0的时候,才说明没有指针指向这块内存,此时内存才能释放。
#include <iostream>
#include <memory>
class Entity{
public:
Entity()
{
std::cout << "created Entity!" << std::endl;
}
~Entity()
{
std::cout << "destroyed Entity!" << std::endl;
}
};
int main() {
{
std::unique_ptr<Entity> entity(new Entity());
std::shared_ptr<Entity> sharedEntity = std::make_shared<Entity>();
std::shared_ptr<Entity> e0 = sharedEntity;
}
std::cin.get();
}
上面代码的运行结果如下:

特点都是离开了{} 范围,就自动销毁。
下面的代码也挺有意思的:
int main() {
{
std::shared_ptr<Entity> e0;
{
std::shared_ptr<Entity> sharedEntity = std::make_shared<Entity>();
e0 = sharedEntity;
}
}
std::cin.get();
}
对这个代码而言,最里边的{}结束时,sharedPtr并不会销毁。因为外部还有引用。只有在e0也结束的时候,才调用了析构函数。
居然还有个weak_ptr,不会增加reference。
int main() {
{
std::weak_ptr<Entity> e0;
{
std::shared_ptr<Entity> sharedEntity = std::make_shared<Entity>();
e0 = sharedEntity;
}
}
std::cin.get();
}
这种情况下,在最内层的{}结束后,sharedEntity就释放了。
感觉到底啥时候用还是不清楚啊~~