所有有 virtual 的类的对象里面最头上就会自动加上一个隐藏的不让你知道的指针, 那个指针叫做 vptr(virtual pointer)
它指向一张表,那张表叫做 vtable, 里面是所有virtual函数的地址
这个 vtable 不是对象的,而是这个类的
如果一个类的函数只要有一个是virtual的,那么它的析构函数也必须是virtual的
所有的oop语言默认都是virtual的,只有C++默认是静态绑定的,所有它才可以说是做成动态绑定的,
c++这样做是因为效率
override 覆盖
void Derived::func()
{
cout << "In Derived func" << endl;
Base::func(); // 在子类的func函数中调用父类的func函数
}
如果在父类中有两个函数重载为虚函数,那么在子类中也必须让这两个函数重载为虚函数,如果子类中只有一个,那么另一个就会被隐藏
发生 namehidding, oop语言中只有C++ 会发生namehidding
如果一个类的成员变量是 referencec(引用) 那么意味着当你去声明它的时候,你没有办法给他一个初始值
然后必须在这个类的构造函数得到初始化列表中给他写出来
一个函数返回一个reference是可以的,和指针一样,不能返回这个函数的本地变量的reference
当要返回一个引用时,写在return哪里的时一个变量,没有其他符号
将一个对象传递进函数,一般用常引用的方法,如果直接传递一个对象进去会发生大量的数据传递,而不是只是一个指针或者变量
引用传参必须给出一个明确的有地址的对象,不能是 f(i * 3) 这样类型的
但是如果是常引用则没问题
learning record code:
#include <iostream>
#include <assert.h>
using namespace std;
const int SIZE = 32;
double myarray[SIZE];
double &subscript(int x)
{
return myarray[12];
}
class A{
public:
int i;
A() : i(10) {}
// virtual void f2() {cout << "" << endl;}
// virtual void f() { cout << "A::f() i = " << i << endl; }
};
class B : public A{
public:
B() : j(20) {}
virtual void f(){ cout << "B::f()" << j << endl; }
int j;
};
// void f(const int &num)
// {
// cout << num << endl;
// }
A f()
{
A a;
return a;
}
int main()
{
A b;
b.i = 20;
f() = b;
for(int i=0; i<SIZE; i++)
{
myarray[i] = i * 1.5;
}
// 表面上看时类型不匹配的, 右边的时一个引用, 左边时一个变量
// 实际上发生的是,将右边的值赋值给左边的变量,发生了非引用
double val = subscript(12);
subscript(3) = 34.5; // 返回的是一个引用,所以可以作为一个变量来使用
// A a;
// B b;
// A *p = &a;
// int *r = (int *) &a;
// int *t = (int *) &b;
// *r = *t;
// p->f();
// cout << sizeof(a) << endl;
// int *p = (int *) &a; // p 和 q 是不一样的,但是*p和*q 是一样的
// int *q = (int *) &b;
// cout << *p << endl;
// cout << *q << endl;
// int *x = (int *) *p;
// cout << x << endl;
return 0;
}