对指针的引用和指针的指针到底是怎么一回事?
#include<iostream>
int i = 47;
int* p = &i;
void f(int** ip)
{
std::cout << "ip :" << ip <<std::endl;
std::cout << "*ip :" << *ip <<std::endl;
std::cout << "**ip :" << **ip <<std::endl;
}
void g(int* &dp)
{
std::cout << "dp :" << dp << std::endl;
std::cout << "*dp :" << *dp << std::endl;
//std::cout << "**dp :" << **dp << std::endl; //error
}
// Error
//void h(int&* p) {}
int main()
{
std::cout << "&i的值:" << &i << std::endl;
std::cout << "i的值:" << i << std::endl;
std::cout << "&p的值" << &p << std::endl;
std::cout << "p的值" << p << std::endl;
std::cout << "*p的值" << *p << std::endl;
f(&p);
g(p);
system("pause");
return 0;
}
指针的引用:两个指针指向同一个变量,解引用的内容相同,不能进行解引用的解引用
指针的指针:第一个指针指向另一个指针地址(第一个指针中存了第二个指针的地址),第一次解引用活得一个指针中的内容(指向一个对象的地址),第二次解引用获得指针内容(地址)中的内容。
函数返回引用到底返回了什么?
函数返回引用,返回了一块不会随着函数结束而结束的内存,所以针对这个返回值,可以把它当作普通对象进行赋值,也可以对其进行引用。
int& f(int& x)
{
std::cout << "&x : " << &x << endl;
return x;
}
int main()
{
int b = 1;
std::cout << "&b " << &b<<endl;
//int c = 1;
//std::cout << "&c" << c;
int& c = b;
std::cout << "&c " << &c<<endl;
int& d = f(b);
int e = 1;
std::cout << "&e " << &e << endl;
e = f(b); //这里是一次赋值运算
std::cout << "&f(b) " << &f(b) << endl;
std::cout << "&d " << &d<<endl;
std::cout << "&e " << &e << endl;
}
从程序运行的结果看,对于f()函数的返回值有两种使用方式,第一种只取其值,这样的话变量有自己的地址。第二种不仅取其值,还取其地址。
拷贝构造函数和默认拷贝构造函数
拷贝构造函数的调用出席在用一个类初始化另一个类的时候。默认拷贝构造函数再将类内的指针传递时采取按值传递的方式这样就会产生多个对象内的指针指向同一个地方。
自定义拷贝构造函数
#include <iostream>
#include <string>
using namespace std;
static int countA = 0;
class A
{
public:
int* AI;
public:
A() :AI(nullptr){
AI = new int(countA);
countA++;
std::cout << "this is A() : " << countA << endl;
}
A(const A &a)
{
AI = new int(*a.AI);
countA++;
std::cout << "this is A(A&) : " << countA << endl;
}
~A() {
countA--;
std::cout << "this is ~A() : " << countA << endl;
if (AI != nullptr);
{
std::cout << "*AI : " << *AI << endl;
std::cout << "AI : " << AI << endl;
}
}
A& operator = (const A& a)
{
AI = a.AI;
std::cout << "this is operator = : " << countA << endl;
return *this;
}
};
void fA(A a) {};
int main()
{
A a1;
A a2 = A(a1);
fA(a1);
}
指针的地址不一样
使用默认拷贝构造函数
#include <iostream>
#include <string>
using namespace std;
static int countA = 0;
class A
{
public:
int* AI;
public:
A() :AI(nullptr){
AI = new int(countA);
countA++;
std::cout << "this is A() : " << countA << endl;
}
/*
A(const A &a)
{
AI = new int(*a.AI);
countA++;
std::cout << "this is A(A&) : " << countA << endl;
}
*/
~A() {
countA--;
std::cout << "this is ~A() : " << countA << endl;
if (AI != nullptr);
{
std::cout << "*AI : " << *AI << endl;
std::cout << "AI : " << AI << endl;
}
}
A& operator = (const A& a)
{
AI = a.AI;
std::cout << "this is operator = : " << countA << endl;
return *this;
}
};
void fA(A a) {};
int main()
{
A a1;
A a2 = A(a1);
fA(a1);
}
指针地址一样。
=赋值运算符重载
#include <iostream>
#include <string>
using namespace std;
static int countA = 0;
class A
{
public:
int* AI;
public:
A() :AI(nullptr){
AI = new int(countA);
countA++;
std::cout << "this is A() : " << countA << endl;
}
A(const A &a)
{
AI = new int(*a.AI);
countA++;
std::cout << "this is A(A&) : " << countA << endl;
}
~A() {
countA--;
std::cout << "this is ~A() : " << countA << endl;
if (AI != nullptr);
{
std::cout << "*AI : " << *AI << endl;
std::cout << "AI : " << AI << endl;
delete AI;
}
}
A& operator = (const A& a)
{
if (this == &a) //避免自赋值
{
return *this;
}
AI = new int (*a.AI);
std::cout << "this is operator = : " << countA << endl;
return *this;
}
};
void fA(A a) {};
int main()
{
A a1;
A a2 = A(a1);
fA(a1);
A a3;
a3 = a1;
}
当对象中有指针时,必须自定义拷贝构造函数 和 赋值运算符 否则在析构函数删除对象时会出错。为了防止出错可以删完在赋值为nullptr(这并不能保证不会出错).
#include <iostream>
#include <string>
using namespace std;
static int countA = 0;
class A
{
public:
int* AI;
public:
A() :AI(nullptr){
AI = new int(countA);
countA++;
std::cout << "this is A() : " << countA << endl;
}
//没有拷贝构造函数会出错
A(const A &a)
{
AI = new int(*a.AI);
countA++;
std::cout << "this is A(A&) : " << countA << endl;
}
~A() {
countA--;
std::cout << "this is ~A() : " << countA << endl;
if (AI != nullptr);
{
std::cout << "*AI : " << *AI << endl;
std::cout << "AI : " << AI << endl;
delete AI;
AI = nullptr;
}
}
A& operator = (const A& a)
{
if (this == &a) //避免自赋值
{
return *this;
}
AI = new int (*a.AI); //这样不会产生错误
//AI = a.AI; //这回产生错误
std::cout << "this is operator = : " << countA << endl;
return *this;
}
};
void fA(A a) {};
int main()
{
A a1;
A a2 = A(a1);
fA(a1);
A a3;
a3 = a1;
}
这个错误就是对于多个对象内的指针变量指向同一个地方,在析构函数中释放内存会产生的错误