[toc]
对象型参数和返回值
image-20210412191002345
class Car {
public:
Car() {
cout << "Car() - " << this << endl;
}
Car(const Car &car) {
cout << "Car(const Car &) - " << this << endl;
}
~Car() {
cout << "~Car() - " << this << endl;
}
void run() {
cout << "run()" << endl;
}
};
void test1(Car car) {
}
main
Car car1;
test1(car1);
Run->
Car() - 0x7ffee2c6d888 Car(const Car &) - 0x7ffee2c6d880 ~Car() - 0x7ffee2c6d880 ~Car() - 0x7ffee2c6d888
产生一些不必要的中间对象
image-20210412191330885void test1(Car &car) { }
Car() - 0x7ffee28d6888 ~Car() - 0x7ffee28d6888
Car test2() {
Car car; // Car()
return car;
}
int main() {
Car car2; // Car()
car2 = test2();
}
Run->
Car() - 0x7ffee66f7888 Car() - 0x7ffee66f7880 ~Car() - 0x7ffee66f7880 ~Car() - 0x7ffee66f7888
匿名对象(临时对象)
image-20210412192428953
class Car {
public:
Car() {
cout << "Car() - " << this << endl;
}
Car(const Car &car) {
cout << "Car(const Car &) - " << this << endl;
}
~Car() {
cout << "~Car() - " << this << endl;
}
void run() {
cout << "run()" << endl;
}
};
void test1(Car car) {
}
Car test2() {
return Car();
}
main
test1(Car());
-> Run
Car() - 0x7ffeee6be888 ~Car() - 0x7ffeee6be888
//main()
Car car2; // Car()
car2 = test2();
Run->
Car() - 0x7ffee9190888 Car() - 0x7ffee9190880 ~Car() - 0x7ffee9190880 ~Car() - 0x7ffee9190888
隐式构造
image-20210412192858140
class Person {
int m_age;
public:
Person() {
cout << "Person() - " << this << endl;
}
Person(int age) :m_age(age) {
cout << "Person(int) - " << this << endl;
}
Person(const Person &person) {
cout << "Person(const Person &person) - " << this << endl;
}
~Person() {
cout << "~Person() - " << this << endl;
}
void display() {
cout << "display() - age is " << m_age << endl;
}
};
//main()
Person p1 = 20;
Run->
Person(int) - 0x7ffee5358888 ~Person() - 0x7ffee5358888
Person p1 = 20; 等价于 Person p2(20);
void test1(Person person) {
}
int main()
{
test1(30);
}
Run->
Person(int) - 0x7ffee91bc888 ~Person() - 0x7ffee91bc888
Person test2() {
return 40;
}
int main()
{
test2();
}
Run->
Person(int) - 0x7ffee3963888 ~Person() - 0x7ffee3963888
//main()
Person p1;
p1 = 40;
Run->
Person() - 0x7ffee84b4888 Person(int) - 0x7ffee84b4880 ~Person() - 0x7ffee84b4880 ~Person() - 0x7ffee84b4888
- 可以通过关键字explicit禁止掉隐式构造
image-20210412193639424
编译器自动生成的构造函数
image-20210412193812470
class Student {
public:
int m_price;
void run() {
}
};
int main() {
Student student;
student.run();
return 0;
}
从汇编可以看到,Student根本没有调用构造函数!这种情况下编译器不会为Student生成默认的构造函数!
image-20210412194043178
- 成员变量在声明的同时进行了初始化
image-20210412194613748
- 有定义虚函数
image-20210412195354777
为什么一旦有虚函数,就会生成构造函数?
当Person对象有事情做,就一定会生成构造函数,需要生成虚表,最前面需要一个指针地址,指向虚表的地址值。相当于虚表是成员变量一样,一旦生成了,就需要给变量赋初值。
- 虚继承了其他类
image-20210412200010789
总结一下
对象创建后,需要做一些额外操作时(比如内存操作、函数调用),编译器一般都会为其自动生成无参的构造函数
友元
image-20210412200555110
class Point {
private:
int m_x;
int m_y;
public:
int getX() { return m_x; };
int getY() { return m_y; };
Point(int x, int y) :m_x(x), m_y(y) {}
void display() {
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
};
Point add(Point p1, Point p2) {
return Point(p1.getX()+p2.getX(),p1.getY()+p2.getY());
}
int main() {
Point p1(10, 20);
Point p2(20, 30);
Point p3 = add(p1,p2);
p3.display();
return 0;
}
Run->
(30, 50)
- 友元函数
- 如果将函数A(非成员函数)声明为类C的友元函数,那么函数A就能直接访问类C对象的所有成员
class Point {
friend Point add(Point, Point);
// friend class Math;
private:
int m_x;
int m_y;
public:
int getX() { return m_x; };
int getY() { return m_y; };
Point(int x, int y) : m_x(x), m_y(y) {}
void display() {
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
};
Point add(Point p1, Point p2) {
return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
int main() {
Point p1(10, 20);
Point p2(20, 30);
Point p3 = add(p1, p2);
p3.display();
return 0;
}
Run->
(30, 50)
- 友元类
class Point {
friend class Math;
private:
int m_x;
int m_y;
public:
int getX() { return m_x; };
int getY() { return m_y; };
Point(int x, int y) : m_x(x), m_y(y) {}
void display() {
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
};
class Math {
public:
Point add(Point p1, Point p2) {
return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
void test() {
Point p1(10, 20);
p1.m_x = 10;
p1.m_x;
}
};
int main() {
Point p1(10, 20);
Point p2(20, 30);
Point p3 = Math().add(p1, p2);
p3.display();
return 0;
}
Run->
(30, 50)
内部类
image-20210412201752301
image-20210412201848584
class Person {
private:
int m_age;
public:
class Car {
private:
int m_price;
};
};
int main() {
Person::Car car1;
Person::Car car2;
Person person;
getchar();
return 0;
}
局部类
image-20210412202219276
int g_age = 10;
void test() {
static int age = 10;
// 局部类
class Car {
public:
void run() {
age = 20;
}
};
Car car;
car.run();
}
int main() {
return 0;
}
特别备注
本系列文章总结自MJ老师在腾讯课堂30小时快速精通C++和外挂实战-大神MJ精选,相关图片素材均取自课程中的课件。