2021-01-05C/C++学习00
请注意,本文编写于 693 天前,最后修改于 693 天前,其中某些信息可能已经过时。

目录


一、前期绑定与动态绑定

1、什么是绑定?

class Base
{
public:
	int x;
public:
	Base()
	{
		x = 100;
	}
    void Function_1()
    {
        printf("Base:Function_1...\n");
    }
    virtual void Function_2()
    {
        printf("Base:Function_2...virtual\n");
    }
};
class Sub:public Base
{
public:
	int x;
public:
	Sub()
	{
		x = 200;
	}
    void Function_1()
    {
        printf("Sub:Function_1...\n");
    }
    virtual void Function_2()
    {
        printf("Sub:Function_2...virtual\n");
    }
};

void TestBound(Base* pb)
{
	int n = pb->x;
	printf("%x\n",n);

	pb->Function_1();

	pb->Function_2();
}
int main(int argc, char* argv[])
{
	return 0;
}

2、什么是前期绑定?什么是后期绑定、动态绑定、运行期绑定?

前期绑定:

当我们的函数写完,编译完的时候他的函数地址就已经确定了,不需要通过间接调用来执行,而是直接CALL了

后期绑定、动态绑定、运行期绑定:

还有一种就是通过间接调用,FF来进行调用,在C++中,动态绑定是通过虚表来实现的
void TestBound(Base* pb)
{
	int n = pb->x;
	printf("%x\n",n);

	pb->Function_1();

	pb->Function_2();//体现出了不同的行为  称为多态
}

总结:

  1. 只有virtual的函数是动态绑定.

  2. 动态绑定还有一个名字:多态

作业

1、定义一个父类:Base 有两个成员X,Y 有一个函数Print(非virtul)

能够打印X,Y的值.

定义3个子类:Sub1 有一个成员A

    Sub2  有一个成员B

    Sub3  有一个成员C

每个子类有一个函数Print(非virtul),打印所有成员.

    Sub1:打印X Y A

    Sub2:打印X Y B

    Sub3:打印X Y C
class Base
{
public:
	int x;
	int y;
public:
	Base()
	{
		x = 1;
		y = 2;
	}
	void Print()
	{
		printf("Base:%x %x\n",x,y);
	}
};

class Sub1:public Base
{
public:
	int A;
public:
	Sub1()
	{
		x = 3;
		y = 4;
		A = 5;
	}
	void Print()
	{
		printf("Sub1: %x %x %x\n",x,y,A);
	}
};

class Sub2:public Base
{
public:
	int B;
public:
	Sub2()
	{
		x = 6;
		y = 7;
		B = 8;
	}
	void Print()
	{
		printf("Sub2: %x %x %x\n",x,y,B);
	}
};

class Sub3:public Base
{
public:
	int C;
public:
	Sub3()
	{
		x = 9;
		y = 0x10;
		C = 0x11;
	}
	void Print()
	{
		printf("Sub3: %x %x %x\n",x,y,C);
	}
};

2、定义一个数组,存储Base Sub1 Sub2 Sub3 使用一个循环语句

调用所有的Print函数。

void Test()
{
	Base b;
	Sub1 s1;
	Sub2 s2;
	Sub3 s3;
	Base* arr[] = {&b,&s1,&s2,&s3};
	for(int i = 0;i < 4; i++)
	{
		arr[i]->Print();
	}
}

3、将上面所有的Print函数改成virtual 继续观察效果.

# include "stdafx.h"

class Base
{
public:
	int x;
	int y;
public:
	Base()
	{
		x = 1;
		y = 2;
	}
	virtual void Print()
	{
		printf("Base - X:%x,Y:%x\n",x,y);
	}
};

class Sub1:public Base
{
public:
	int A;
public:
	Sub1()
	{
		x = 3;
		y = 4;
		A = 5;
	}
	virtual void Print()
	{
		printf("Sub1 - X:%x,Y:%x,A:%x\n",x,y,A);
	}
};

class Sub2:public Base
{
public:
	int B;
public:
	Sub2()
	{
		x = 6;
		y = 7;
		B = 8;
	}
	virtual void Print()
	{
		printf("Sub2 - X:%x,Y:%x,B:%x\n",x,y,B);
	}
};

class Sub3:public Base
{
public:
	int C;
public:
	Sub3()
	{
		x = 9;
		y = 0x10;
		C = 0x11;
	}
	virtual void Print()
	{
		printf("Sub3 - X:%x,Y:%x,C:%x\n",x,y,C);
	}
};

void Test()
{
	Base b;
	Sub1 s1;
	Sub2 s2;
	Sub3 s3;

	Base* arr[] = {&b,&s1,&s2,&s3};

	for(int i = 0;i < 4; i++)
	{
		arr[i]->Print();
	}
}

int main(int argc, char* argv[])
{
	Test();
	return 0;
}

4、思考题:为什么析构函数建议写成virtual的?

否则析构函数释放的就是父类(基类)的内存

5、写一个例子程序,能体现多态的作用.

总结

  1. 一种类型能够体现不同的行为,称之为多态,比如同样是一个Base,在不同的情况下执行不同的方法。
  2. 多态 又可以称为 动态绑定
  3. 绑定分为:前期绑定动态绑定
  4. 在C++里 动态绑定是 通过虚表来实现的

多态的好处与作用
笔记来自滴水三期

本文作者:Na1r

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!