1.指针
C++的精髓之一就是多态性,只有指针或者引用可以达到多态。
使用指针的好处:
第一实现多态。
第二在函数调用,传指针参数。不管你的对象或结构参数多么庞大,你用指针,传过去的就是4个字节。如果用对象,参数传递占用的资源就太大了。
类对象和类指针:
类的对象:用的是内存栈,是个局部的临时变量。
类的指针:用的是内存堆,是个永久变量,除非你释放它。
类和对象是两回事,对象是类的实例;
对象是在栈中分配的,使用new生成的对象是在堆中分配的;
要发挥虚函数的强大作用,必须使用指针来访问对象.
具体不同看代码:
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
static int number;
string name;
public:
Student() { }
void set(string str)
{
name = str;
number++; // 调用静态数据成员
}
void print() // 态成员函数 print()
{
std::cout << name <<" : The number of the students is " << number << " numbers." << std::endl; // 调用静态数据成员
}
};
int Student::number = 0; // 静态数据成员初始化
int main(int argc, char** argv)
{
Student* s1;
s1 = new Student();
s1->set("111");
Student s2;
s2.set("222");
s1->print();
s2.print();
system("pause");
return 0;
}
s1 是类指针,s2是类对象。类指针是内存地址值,指向内存中存放的类对象;类对象是利用类的构造函数在内存中分配一块内存。
关于指针的简单使用
int x = 1;
int *p = &x;
cout<<"x = "<<x <<endl;
cout<<"p = "<<p <<endl; //指针p指向x的地址
cout<<"&x= "<<&x<<endl; //获取x的地址
cout<<"&p= "<<&p<<endl; //获取指针p的地址
指向指针的指针
int x = 188;
int *p = &x;
int **pp = &p;
cout<<"x = "<<x <<endl; //x = 188
cout<<"x的地址是 = "<<&x <<endl; //结果是x的地址,0x61fd8c
cout<<"-----------------------"<<endl;
cout<<"一级指针p的值是 "<<p <<endl; //结果是x的指针,0x61fd8c
cout<<"一级指针指向的地址是 "<<&p<<endl; //指针p的地址,0x61fd80
cout<<"一级指针指向的地址存放的数值是 "<<*p<<endl;//指针p指向地址存放数值 188
cout<<"-----------------------"<<endl;
cout<<"二级指针pp的值是 "<<pp <<endl; //结果是指向p的地址,0x61fd80
cout<<"二级指针指向的地址是 "<<&pp<<endl;//指向pp的地址,0x61fd78
cout<<"二级指针指向的内存地址存放的数值 "<<*pp<<endl;//结果是p的地址存放的数值,0x61fd8c
cout<<"二级指针指向的一级指针存放地址数值的地址"<<**pp<<endl;//结果是188
数值 | 地址 | |
x | 188 | 0x61fd8c |
p | 0x61fd8c | 0x61fd80 |
pp | 0x61fd80 | 0x61fd78 |
指向数组的指针
char x[8] = "ABCDEFG";
char *p;
//指针指向的是数组中每一个值的地址
for(p = &x[0]; p < &x[7]; p++){
cout<<*p<<" ";
}
cout<<endl;
指针数组
char x[] = "ABCDEFGh";
int length = sizeof(x)/sizeof(x[0]);
char *p[length];
for(int i = 0; i < length; i++){
//指针数组,
p[i] = &x[i];
}
for(int i = 0; i < length; i++){
cout<<*p[i]<<" ";
}
cout<<endl;
指向指针数组的指针
char x[] = "ABCDEFGh";
int length = sizeof(x)/sizeof(x[0]);
char *p[length]; //指针数组
for(int i = 0; i < length; i++){
p[i] = &x[i];
}
for(int i = 0; i < length; i++){
cout<<*p[i]<<" ";
}
char **pp =NULL;
for(pp = p; pp< p+length ; pp++){
cout<<**pp<<" ";
}
cout<<endl;
二维数组指针(重点)
int x[2][3] = {1,2,3,4,5,6};
int (*p)[3] = x; //也可以写作 int (*p)[3] = &x[0]
cout<<p<<" "<<*p <<" "<<**p<<endl;
cout<<x[0]<<" "<<x[0][0]<<endl;
cout<<&x[0][0]<<endl;
cout<<p+1<<" "<<*(p+1) <<" "<<**(p+1)<<endl;
cout<<x[1]<<" "<<x[1][1]<<endl;
cout<<&x[1][0]<<endl;
//指向第二个元素
cout<<*(*p+1)<<endl;
//第二个元素的地址
cout<<&*(*p+1)<<endl;
这里使用的是行指针,每行有三个元素,类型是int (*)[3],
如果取第二行第二列的元素,先 *(p+1) 再 *(p+1)+1 最后*(*(p+1)+1)
首先p指向二维数组的首地址,*p指向二维数组中第一维的首地址,它们两个的值相同。**p就是第一个元素的值。
x[0]是二维数组第一维的首地址,&x[0][0]是第一个元素的地址 ,它们两个的值相同。x[0][0]是第一个元素的值。
2.线程thread
#include <iostream>
#include<thread>
#include<unistd.h>
#include<mutex>
using namespace std;
std::mutex mymutex;
void Hello_thread();
void World_thread();
int main()
{
thread threadHello(&Hello_thread);
thread threadWorld(&World_thread);
threadHello.join();
threadWorld.join();
return 0;
}
void Hello_thread()
{
int k=0;
unique_lock<mutex> lock(mymutex);
while(k<2)
{
k++;
cout<<endl<<"hello"<<endl;
sleep(2);
}
}
void World_thread()
{
unique_lock<mutex> lock(mymutex);
int k = 0;
while( k < 10)
{
cout<<endl<<"world"<<endl;
sleep(1);
k++;
}
}
std::unique_lock为锁管理模板类,是对通用mutex的封装。
std::unique_lock对象以独占所有权的方式(unique owership)管理mutex对象的上锁和解锁操作,
即在unique_lock对象的声明周期内,它所管理的锁对象会一直保持上锁状态;
而unique_lock的生命周期结束之后,它所管理的锁对象会被解锁。
参考: