1_封装

封装

结构体可以做参数传递吗 ?

可以. 传到堆栈里面.

编译器并不能传递你的这个结构体, 它里面参数的个数, 所以编译器没有用 push 而是用 mov 传参数. 先修改 esp 开辟局部空间, 然后用 mov 指令一个一个把传过来的参数移动到寄存器里面去. 这个本质和之前传递 int 是一样的.

但是我们写的时候, 不要把结构体当作参数, 因为大量的内存复制, 效率太低. 那么解决办法就是传递结构体指针.

struct  Student
{
    int a;
    int b;
    int c;
    int d;
}

int Plus(Student s)
{
    return  s.a + s.b + s.c + s.d;
}

分析下这个函数是如何传递参数的

C++ 就是编译器在 C 的基础上多做了一些事情.

sturct  Student
{
    int a;
    int b;
    int c;
    int d;

    int Plus()
    {
        return  a+b+c+d;
    }
}
sturct  Student
{
    int a;
    int b;
    int c;
    int d;
}

int Plus(Student* p)
{
    return  p->a + p->b + p->c + p->d;
}

总结, 如果把函数放到结构体里面的话, 编译器替我们传参, 传的这个参数就是当前的结构体的地址.

我们把函数这样放到结构体里面的话, 结构体可以直接传递到函数里面去, 没有必要像以前那样一个个用指针访问结构体成员了.

把函数定义在结构体里面的这种语法, 叫作封装. 封装的好处就是函数可以非常方便地使用结构体里面的其它成员.

什么是类, 带有函数的结构体, 称为类.

什么是成员函数, 结构体里面的函数, 称为成员函数.

虽然你把函数定义在结构体里面了, 但是看汇编就知道, 这个函数并不占用结构体的空间.

int main(int argc, char* argv[])
{
    Student s = {1, 2, 3, 4};

    s.Plus();       // 只有这样写编译器才能找到这个函数

    return 0;
}

但是注意, 这么写并不是说这个函数变成局部的了, 这么写仅仅是为了给编译器看. s.Plus 仅仅是告诉编译器, 我用的是哪个结构体里面的 Plus().