一、this指针:
1.作用:
类的每个成员函数中都有一个指针叫this,指向调用成员函数的那个对象。
1.是一个指针,指向对象本身,
2.this只能在类的内部使用,
在类的内部调用成员都是使用this调用的,可以省略
示例2:
#include <iostream> using namespace std; class Person private: int age; public: Person(int age) { this->age = age;//this->age 是指向当前构造函数的对象的age } void show() { cout<<this->age<<endl;//就算这里不写this,系统也会给我们补上this,在成员函数中调用成员都是通过this指针调用的。不写this属于隐式调用this } }; int main() { Person p(1);//创建对象p,所以这里执行构造函数时,构造函数的this指向p p.show();//show中this指向p,因为p调用show }
2.this的一般用法
指向对象本身
this指向的是哪个对象?指向当前正在调用成员函数的对象。
this存在的意义:在类的内部,将当前对象当做参数进行传递
示例:
#include <iostream> using namespace std; class Person; void printPerson(Person* p); class Person { private: int age; int score; public: Person(int age, int score) { this->age = age; this->score = score; } void show() { cout<<age<<" "<<score<<endl; } void doSomething() { printPerson(this);//当前对象 person* p对象的指针传递过去了 } }; void printPerson(Person* p)//Person* ptr_p = p对象的指针 { p->show(); } int main() { Person p(10, 20); p.doSomething(); Person p2(30, 40); p2.doSomething(); return 0; }
类声明:
#include <iostream> using namespace std; class B;//声明对象时,不创建对象 class A { public: B* p; A() { p = new B; } }; class B { }; int main() { A a;//编译错误 return 0; }
练习1:
Person类,包含私有属性:姓名name,性别bool gender,年龄age,另一个对象的指针 Person *lover(爱人);
1.构造函数初始化成员变量 name gender
2.成员函数setAge给年龄赋值
3.成员函数marry(Person& other) 输出name"和"other.name"喜结良缘!";
4.成员函数show(); 输出"大家好!我是"gender,name,今年"age;
输出"爱人是:"lover->name;
private: string name; bool gender; int age; Person *lover;
#include <iostream> using namespace std; class Person { string name; bool gender; int age; //指向另外一个person类型的对象指针 Person* lover; public: Person(string name,bool gender):name(name),gender(gender) { } void setAge(int age) { this->age = age; } void marry(Person& other)//p2 { //当前调用者(邓超)的爱人是孙俪 this->lover = &other; //孙俪的爱人是邓超 other.lover = this; cout<<this->name<<" "<<other.name<<"在一起"<<endl; } void show() { cout<<"大家好,我是"<<(gender?"帅哥":"美女")<<name<<",今年" <<age<<"岁"<<endl; cout<<"我的爱人是"<<lover->name<<endl; } }; int main() { Person p1("邓超",true); p1.setAge(48); Person p2("孙俪",false); p2.setAge(24); p1.marry(p2); p1.show(); p2.show(); return 0; }
二、拷贝构造函数
思考:下面代码输出几次 "student"
class Student { public: Student() { cout<<"student"<<endl; } private: //string m_name; }; int main() { Student stu1;//创建对象调用构造函数 Student stu2 = stu1;//使用同类型一个对象初始化另一个对象,这就是复制对象,会调用拷贝构造函数 Student stu3(stu1);//使用同类型一个对象初始化另一个对象,这就是复制对象,会调用拷贝构造函数 }
1.声明:
函数名(类名)(const 类名 &对象名)
使用一个对象初始化另一个对象的时候调用拷贝构造
拷贝构造函数的参数列表必须是 const 类名 &对象名。
示例1:
#include <iostream> using namespace std; class Person { private: int age; public: Person(int age) { this->age = age; } //根据参数列表判断这是拷贝构造函数,Person类型的拷贝构造函数,参数必须是Perosn类型 Person(const Person& other) { cout<<"拷贝构造"<<endl; this->age=other.age; } void show() { cout<<this->age<<endl; } }; int main() { Person a(19); cout<<"start"<<endl; Person b(a);//调用对象b 的拷贝构造函数 Person c = a; cout<<"end"<<endl; b.show(); }
2.默认拷贝构造函数
1)在没有显式的定义拷贝构造函数时,系统会自动生成一个拷贝构造函数,
功能:将成员变量逐个赋值
2)如果显式的定义拷贝构造函数,并且运行时执行了拷贝构造函数,
那么默认拷贝构造函数和默认构造函数都不会被调用了
3)创建一个对象的时候,只会调用一个构造函数
默认的构造:一个构造函数都没有
默认的拷贝构造:没有拷贝构造存在
写了拷贝构造的时候,默认的构造函数还在不? 不在了
示例2:
#include <iostream> using namespace std; class Person { private: int age; public: Person(int age):age(age) { } //Person类中没有显式的定义拷贝构造函数 int getAge() { return age; } }; int main() { Person* p = new Person(19);//在堆空间创建一个对象 Person* p2 = new Person(*p);//*p是一个Person对象,这里是使用同类型的一个对象初始化另一个对象,调用拷贝构造函数,但是在Person中没有显式的定义拷贝构造函数,所以这里调用默认拷贝构造函数 cout<<p->getAge()<<endl;, cout<<p2->getAge()<<endl; }
总结:
1. 如果没有自定义的拷贝构造函数则系统自动生成一个默认的拷贝构造函数
Empty(const Empty& o) { //this->age = o.age; }
2. 当使用一个对象实例化另外一个新对象时,系统自动调用拷贝构造函数
Person p;//构造函数 Person p2 = p;//拷贝构造函数 Perosn p3(p);//拷贝构造函数
3. 系统默认拷贝构造函数的功能:逐个对成员变量进行赋值
4. 显示的定义了拷贝构造函数,系统默认的就不存在了,
函数的功能(对变量进行的赋值),就由我们自己来完成了