封装是面向对象编程中的一个重要概念,它把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。封装可以理解为一种信息隐藏技术,通过封装,对象的内部状态信息被隐藏在对象内部,只通过已定义的接口对外提供操作。
封装是面向对象编程中的一个重要概念,它把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。封装可以理解为一种信息隐藏技术,通过封装,对象的内部状态信息被隐藏在对象内部,只通过已定义的接口对外提供操作。
接上一章节继续:第六章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人 – 菜鸟资源 (xiciw.com)
4.6. this 指针
4.6.1. 意义
系统在创建对象时,默认生成的指向当前对象的指针。这样作的目的,就是为了带来方便。
4.6.2. 作用
1,避免构造器的入参与成员名相同。
2,基于 this 指针的自身引用还被广泛地应用于那些支持多重串联调用的函数中。
比如连续赋值。
#include <iostream>
using namespace std;
class Stu
{
public:
Stu(string name, int age)
{
this->name = name;
this->age = age;
}
Stu & growUp()
{
this->age++;
return *this;
}
void display()
{
cout<<name<<" : "<<age<<endl;
}
private:
string name;
int age;
};
int main()
{
Stu s("wangguilin",30);
s.display();
s.growUp().growUp().growUp().growUp().growUp();
s.display();
return 0;
}
3.this 指针是 const
Stu* const & growUp()
{
this->age++;
return this;
}
s.growUp()->growUp()->growUp()->growUp();
4.7. 赋值运算符重载(Operator=)
4.7.1. 发生的时机
用一个己有对象,给另外一个己有对象赋值。两个对象均己创建结束后,发生的赋值行为。
4.7.2. 定义
类名
{
类名& operator=(const 类名& 源对象)
拷贝体
}
class A
{
A& operator=(const A& another)
{
//函数体
return *this;
}
};
4.7.3. 规则
1. 系统提供默认的赋值运算符重载,一经实现,不复存在。
2.系统提供的也是等位拷贝,也就浅拷贝,一个内存泄漏,重析构。
3.要实再深深的赋值,必须自定义。
4.自定义面临的问题有三个:
⑴自赋值
⑵内存泄漏
⑶重析构。
5.返回引用,且不能用 const 修饰。其目的是实现连等式。
4.8. 返回栈上引用与对象
4.8.1. 返回栈对象
class A
{
public:
A(){}
A(const A &a)
{
cout<<"cp contructor"<<endl;
}
};
a 传值:发生拷贝
void foo(A a)
{}
int main()
{
A a;
foo(a);
return 0;
}
b 传引用 没有发生拷贝
void foo(A& a)
{}
int main()
{
A a;
foo(a);
return 0;
}
c 返回对象
A foo(A& a)
{
return a;
}
int main()
{
A a;
foo(a);
return 0;
}
在 main 的栈上事先开辟了一个临时空间,把这个空间的地址隐式的转到 foo 函数栈上。然后,把 a 内的东西,拷贝到临时空间中。 所以发生一次构造,一次拷贝,两次析构。
测试:
A foo(A& a)
{
cout<<"in foo :"<<(void*)&a<<endl;
return a;
}
int main()
{
A a;
A t = foo(a);
cout<<"in main:"<<(void*)&t<<endl;
return 0;
}
此时 main 函数中产生的临时空间,由 t 来取而代之。所以也发生一次构造,一次拷贝,两次析 构。发现 t 的地址,同 a 的地址相同。
以上 windows 和 linux 相同,linux 作了更深层次的优化,
A foo(A& a)
{
A b;
cout<<"in foo :"<<(void*)&b<<endl;
return b;
}
int main()
{
A a;
A t = foo(a);
cout<<"in main:"<<(void*)&t<<endl;
return 0;
}
此时发生了两次构造,两次析构。也就是 main 中的 t 取代了临时空间,而 b 的构造完
成了 t 的构造。所在完成了两次构造,两次析构。而不是三次。
4.8.2. 返回栈对象引用
返回栈对象的引用,多用于产生串联应用。比如连等式。 栈对象是不可以返回引用的。
除非,函数的调用者返回自身对象。
比如:
MyString & MyString::operator=(const MyString & another)
{
if(this == &another)
return *this;
else
{
delete []this->_str;
int len = strlen(another._str);
this->_str = new char[len+1];
strcpy(this->_str,another._str);
return *this;
}
}
提高:非要返回栈引用会发生什么
class A
{
public:
A(){
cout<<"constructor"<<endl;
}
A(const A &a)
{
cout<<(void*)this<<" "<<&a<<" cp contructor"<<endl;
}
~A()
{
cout<<(void*)this<<" destructor"<<endl;
}
int a;
};
A& func()
{
A a;
cout<<"in func:"<<&a<<endl;
return a;
}
int main()
{
A t = func();
cout<<"int main:"<<&t<<endl;
return 0;
}
案例系统 string 与 MyString 在下一章才菜鸟资源精讲课程讲解
😎