C++面向对象基础——函数与对象总结

面向对象最后一节课了~

引入

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A
{
public:
int a;
void test(int num) {
a += num;
}
};
void test(A* obj, int num) {
obj->a += num;
}
int main() {
A obj;
obj.test(100);
test(&obj, 100);
}

效率

以上代码中的 A::test 函数和 test 函数实现了相同的功能。这种情况下,效率永远是类内的函数比全局函数的效率高的。这也就是为什么作用域我们会倾向于小的处理,就近原则嘛。

成员函数调用方式

这里成员函数的理解就理解为整个类的就行了,它不属于一个个体。

成员函数直接调用实际上跟全局函数调用一模一样,因为在编译器就已经确定了成员函数的位置,用对象无论调用的是虚函数还是非虚函数,结果都是一致的,因为它这里认为你一定不会是多态,所以不访问虚函数表,直接访问固定地址即可。你都没有指针,你生成的类一定是那个类,这么理解就可以了。

在可能发生多态的情况下就会查找类的虚函数表,找到对应的函数。因为你用指针实例化了一个对象你可以实例化它的子类,一个动物的指针可能指到了具体的猫这个对象上面,也可能指到了狗的上面,那么它们的一些方法(比如吃)就肯定不是固定的一个操作,所以需要查找虚函数表,调用对应的可能已经被重写过的方法了。

给个例子吧:

在类(A)内的一个 test 函数中,有如下三种调用(testA),请问哪些会使用虚函数表调用,哪些是固定地址调用?

1
2
3
testA();
this->testA();
A::testA();

最后一个其实比较清楚,最后一个肯定是固定地址调用,因为你规定好了它的作用域的指定函数名,那它地址就是固定的。

第二个也很清楚,因为我们熟知的指针调用,也是这种模式的,那它肯定是虚函数表调用的。

主要是第一个,那这里需要解释一点:类内调用函数或者成员变量,是隐含的this指针访问。

new和delete

new 和 delete 算得上是C++的一个运算符,它的作用仅仅是快速帮你完成空间分配并返回相应类型的指针,它内部会调用重载函数,对每个类来说,new 调用的函数都不一样,因为每个类大小也不一样,但是内部最终都调用malloc分配足够的空间,如果是类的化,有相应的构造函数还会调用对应的构造函数。同样,我们使用 malloc 也能分配这样的一个空间,但是它仅仅能分配空间,它并不能帮你调用构造函数,如果想达到相同的效果还需要手动调用它的构造函数,并且因为对象空间啥都没有,因此只能指定作用域去调用构造函数。

同 new 和 malloc 一样,delete 和 free 也和它们关系一样。只是 delete 不仅帮你调用 free,还会额外帮你调用析构函数。具体顺序是先调用析构函数,再调用 free 去释放空间,为什么是这个顺序应该也很好理解,因为你的对象上面可能还有一些指针分配的空间,如果你直接把对象空间释放掉了,那么对象所用的空间就会无人去用,但它不会被标记为释放,这个内存就一直在这了,所以我们需要先析构,再free。

C++的面向对象在此完结撒花了,作为信竞选手,我一直以为我 C++ 没什么问题,可是认真学了才知道原来自己差的还远awa,明天开始新知识的学习了!