C/C++(六)多态
本文将介绍C++的另一个基于继承的重要且复杂的机制,多态。
一、多态的概念
多态,就是多种形态,通俗来说就是不同的对象去完成某个行为,会产生不同的状态。
多态严格意义上分为静态多态与动态多态,我们平常说的多态一般指动态多态。(后文介绍的多态也是动态多态,只在本部分介绍一下静态多态)
1、静态多态
静态多态又称作静态绑定(早绑定、前期绑定),即在函数编译期间就决定了程序的行为(即函数名修饰规则,具体C/C++(二)中有详细描述)。
平常最经常用的静态多态就是函数重载。
2、动态多态
动态多态又称作后期绑定,在程序运行期间再根据具体拿到的类型来调用具体的函数,确认程序的具体行为。
我们平常说的多态一般指动态多态,静态动态一般就说函数重载。
二、多态(动态多态)
从技术方面来说,多态就是不同继承关系下的类对象,去调用同一函数(调用的函数必须是虚函数,后文会介绍),会产生不同行为。
1、多态的构成条件
1、调用的函数必须是虚函数,且派生类必须为基类的虚函数进行重写。
2、必须用父类的指针 / 引用来调用虚函数。
(为什么必须传父类的指针 / 引用?这里初步解释,后面会在原理部分详细解释——因为父子类的赋值兼容原则,子类可以切片赋值给父类,父类却不能赋值给子类,因为可能会缺成员)
(那又为什么必须传指针 / 引用?因为传对象的话,子类只会把父类的那一部分成员拷贝过去,但是不会拷贝虚函数表指针,就不能成功调用对应的虚函数了)
2、虚函数
被 virtual 修饰的类成员函数称为虚函数。
class Person { public:// 虚函数virtual void BuyTicket() { cout << "买票-全价" << endl;} };
2.1 虚函数的重写(多态的条件之一)
如果派生类中存在与父类完全相同(函数名、函数返回值、函数参数都完全相同)的虚函数,就称作派生类的虚函数重写了父类的虚函数。
#include <iostream> using namespace std;class Person { public:virtual void BuyTicket(){cout << "全价购票" << endl;} };class Student :public Person { public:/*子类重写父类虚函数时,如果不加 virtual 关键字,虽然也可以构成重写(子类继承下来父类的虚函数,仍旧保持虚函数属性)但是这种写法不规范,可读性较差,建议不要这么做*/virtual void BuyTicket(){cout << "半价购票" << endl;} };void Test(Person& p) {p.BuyTicket(); }int main() {Person p;Student s;Test(p);Test(s);return 0; }
2.2 多态的两个特殊情况
2.1.1 协变(基类与派生类的虚函数返回值类型不同的时候)
当派生类重写父类虚函数的时候,基类与派生类的虚函数的返回值类型可以不同,但是必须是父类 / 子类的指针或引用。
当派生类虚函数返回值是父类 / 子类的指针或引用时,称作协变。
2.2.2 析构函数的重写
如果基类的析构函数也是虚函数,这个时候只要派生类定义了析构函数,不论是否加了 virtual 关键字,都视作对基类的析构函数构成重写。
(虽然基类和派生类的析构函数名字不同,看似违背了虚函数的重写原则,实际上编译器会对析构函数的名称做特殊处理,在编译后,所有析构函数的名称都会统一处理成 destructor)
#include <iostream> using namespace std;class Person { public:virtual ~Person() { cout << "~Person()" << endl; } };class Student : public Person { public:virtual~Student() { cout << "~Student()" << endl; } };// 只有派生类Student的析构函数也定义了析构函数,下面的delete对象调用析构函数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。 int main() {Person* p1 = new Person;Person* p2 = new Student;delete p1;delete p2;return 0; }
3、C++11检测虚函数是否重写的两个关键字
从上文的介绍可以看出,C++对虚函数的重写要求比较严格。在有些情况下(比如函数名、返回值字母写反写错),可能会无法构成重写,导致无法构成多态。
但是这种错误在编译期间是不会报出的,只有在程序运行时才会发现,与预期结果不符,这个时候才来debug,得不偿失。
因此C++11标准提供了两个帮助用户检测是否完成重写的关键字:final 和 override
3.1 final
final 修饰某个虚函数,则这个虚函数不能再被重写
3.2 override
override 修饰派生类虚函数,检查派生类的虚函数是否基类的某个虚函数的重写,如果不是(比如拼写错了),编译报错。
4、纯虚函数与抽象类
在虚函数的后面加上 =0 ,这样的虚函数称作纯虚函数。
包含纯虚函数的类叫做抽象类(又叫接口类,在某类不代表具体实体的时候可以使用;另一个意义是说明多态想在其多个子类中实现),抽象类不能实例化出对象。
继承抽象类的派生类也不能实例化出对象,只有当这个派生类对纯虚函数进行重写,这个派生类才能实例化出对象。
因此纯虚函数在某种程度上间接强制了派生类的重写,更体现了接口继承思想。
(接口继承与实现继承:
普通函数的继承是一种实现继承,继承的是函数的实现,目的是使用这个函数;
虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写达成多态。)
三、多态的实现原理(重点)
1、代码引入
#include <iostream>
using namespace std;class Test
{
public:virtual void test(){cout << _num << endl;}
private:int _num = 1;
};int main()
{Test t;printf("%d", sizeof(Test));
}
让我们猜猜,sizeof(Test) 应该是多少?
很多人可能会说,函数储存在代码段里,不算在类大小里面,那就应该是4字节(32位系统) / 8字节(64位系统)?
但实际上:
这是为什么?
通过内存窗口的观察我们可以看见,Test对象里面除了储存了_num 成员变量,还储存了一个叫做_vfptr的指针变量,而一切指针变量大小在32位系统下都是4字节,在64位系统下都是8字节。
这个_vfptr是什么?这个指针我们叫做虚函数表指针,指向虚函数表。(v代表virtual,f 代表function)
2、虚函数表
虚函数表的本质,是储存着一个类里面的所有虚函数地址的一个指针数组。(一般情况下这个数组最后会放一个nullptr作为虚函数表的终止标记。)(注意:不是储存着虚函数,是储存着虚函数的地址,虚函数还是储存在代码段里的)
我们给出一个多态的代码:
#include <iostream> using namespace std;class Base { public:virtual void Func1(){cout << "Base::Func1()" << endl;}virtual void Func2(){cout << "Base::Func2()" << endl;}void Func3(){cout << "Base::Func3()" << endl;} private:int _b = 1; };// 派生类Derive继承Base并重写Func1 class Derive : public Base { public:virtual void Func1(){cout << "Derive::Func1()" << endl;} private:int _d = 2; };int main() {Base b;Derive d;return 0; }
调用一下监视窗口:
我们可以发现:
1、派生类对象 d 由两部分构成,继承自父类的成员,和自己的成员
2、派生类和父类都有一个虚函数表指针,指向各自的虚函数表,虚函数表里面储存着虚函数的地址。
3、派生类的虚函数表和父类的虚函数表不一样,由于Func1完成了重写,所以d的虚表
中存的是重写的Derive::Func1;派生类完成重写了的虚函数覆盖了原有的父类虚函数。
所以虚函数的重写也叫作覆盖,覆盖就是指虚表中虚函数的覆盖。重写是语法的叫法,覆盖是原理层的叫法。
4、派生类其实把父类的三个函数都继承了下来,但是由于Func3不是虚函数,所以并未放到虚函数表中。
派生类虚函数表的生成流程:
1、先把基类的虚函数表拷贝到自己的虚函数表中
2、如果派生类重写了某个虚函数,在虚函数表中用这个虚函数地址覆盖原父类的虚函数地址3、派生类如果自己增加了虚函数,按照在派生类中的声明次序依次放到派生类虚函数表的后3、多态的原理
3、多态的实现原理
还是直接上代码:
#include <iostream> using namespace std;class Person { public:virtual void BuyTicket() { cout << "买票-全价" << endl; } };class Student : public Person { public:virtual void BuyTicket() {cout << "买票-半价" << endl; } };void Func(Person& p) {p.BuyTicket(); }int main() {Person Mike;Func(Mike);Student Johnson;Func(Johnson);return 0; }
观察多态实现代码图:
观察红色箭头可以看到,p在指向mike对象时,p->BuyTicket从mike的虚表中找到的虚
函数是Person::BuyTicket。
观察蓝色箭头可以看到,p在指向johnson对象时,p->BuyTicket在johson的虚表中
找到的虚函数是Student::BuyTicket。
这样就实现出了不同类的对象去调用同一函数时,展现出不同的形态。
再看一下汇编代码:
// 与多态无关的汇编代码都已去除 void Func(Person* p) { ...p->BuyTicket(); // p中存的是mike对象的指针,将p移动到eax中 001940DE mov eax,dword ptr [p] // [eax]就是取eax值指向的内容,这里相当于把mike对象头4个字节(虚表指针)移动到了edx 001940E1 mov edx,dword ptr [eax] // [edx]就是取edx值指向的内容,这里相当于把虚表中的头4字节存的虚函数指针移动到了eax 00B823EE mov eax,dword ptr [edx] // call eax中存虚函数的指针。这里可以看出满足多态的调用,不是在编译时确定的,是运行起来 以后到对象的中取找的。 001940EA call eax 00头1940EC cmp esi,esp } int main() { ... // 首先BuyTicket虽然是虚函数,但是mike是对象,不满足多态的条件,所以这里是普通函数的调 用转换成地址时,是在编译时已经从符号表确认了函数的地址,直接call 地址mike.BuyTicket(); 00195182 lea ecx,[mike] 00195185 call Person::BuyTicket (01914F6h) ... }
就可以明白,满足多态以后的函数调用,不是在编译时确定的,是运行起来以后到对象的中取找的。不满足多态的函数调用时编译时确认好的,因此叫做动态多态。
4、多态是如何实现的?(一句话总结)
首先,多态是一种基于继承和虚函数实现的机制,派生类必须实现对虚函数的重写,用来调用虚函数的函数必须传父类的指针或引用;然后,基类和派生类各有一张虚函数表,通过传参的不同(父类直接传,子类切片),对象内部的虚函数表指针会去各自的虚函数表里面寻找对应的虚函数地址,从而实现调用同名函数时产生不同的行为,达到多态的效果。
5、有关多态的一些小问题:
如果子类不重写虚函数,父子类的虚函数表一样吗?
储存的虚函数的地址是一样的,但是虚函数表毕竟是两张表,储存虚函数表的地方不一样,是分开存储的!
如果有许多同类对象,它们的虚函数表一样吗?
一样!同类对象共用一张虚函数表!
也就是说,虚函数表本质其实是个静态常量,被所有同类对象共享!
四、多继承关系下的虚函数表
之前所说的是单继承关系下的虚函数表,那么多继承关系下的虚函数表是什么样的?
(PS:菱形继承和菱形虚拟继承太过复杂,这里只介绍普通多继承)
继续上代码:
#include <iostream>
using namespace std;class Base1
{
public:virtual void func1(){cout << "Base1::func1" << endl;}virtual void func2(){cout << "Base1::func2" << endl;}
private:int b1;
};class Base2
{
public:virtual void func1(){cout << "Base2::func1" << endl;}virtual void func2(){cout << "Base2::func2" << endl;}
private:int b2;
};class Derive : public Base1, public Base2
{
public:virtual void func1(){cout << "Derive::func1" << endl;}virtual void func3(){cout << "Derive::func3" << endl;}
private:int d1;
};// 先给虚函数函数指针取个别名VFPTR
typedef void(*VFPTR) ();void PrintVTable(VFPTR vTable[])
{cout << " 虚表地址>" << vTable << endl;for (int i = 0; vTable[i] != nullptr; ++i){printf(" 第%d个虚函数地址 :0X%x,->", i, vTable[i]);VFPTR f = vTable[i];f();}cout << endl;
}int main()
{Derive d;/*思路:取出b、d对象的头4bytes,就是虚表的指针,前面我们说了虚函数表本质是一个存虚函数指针的指针数组,这个数组最后面放了一个nullptr1、先取b的地址,强转成一个int*的指针2、再解引用取值,就取到了b对象头4bytes的值,这个值就是指向虚表的指针3、再强转成VFPTR*,因为虚表就是一个存VFPTR类型(虚函数指针类型)的数组。4、虚表指针传递给PrintVTable进行打印虚表5、需要说明的是这个打印虚表的代码经常会崩溃,因为编译器有时对虚表的处理不干净,虚表最后面没有放nullptr,导致越界,这是编译器的问题。我们只需要点目录栏的-生成-清理解决方案,再编译就好了。*/VFPTR* vTableb1 = (VFPTR*)(*(int*)&d);PrintVTable(vTableb1);VFPTR* vTableb2 = (VFPTR*)(*(int*)((char*)&d + sizeof(Base1)));PrintVTable(vTableb2);return 0;
}
可以发现,派生类继承了几个包含虚函数的父类,就有几个虚函数表。(派生类自己独有的虚函数,会存放在第一个继承的基类的虚表里,但是由于编译器的BUG,并没有展示在内存窗口里面,可以通过下图观察到)
相关文章:
C/C++(六)多态
本文将介绍C的另一个基于继承的重要且复杂的机制,多态。 一、多态的概念 多态,就是多种形态,通俗来说就是不同的对象去完成某个行为,会产生不同的状态。 多态严格意义上分为静态多态与动态多态,我们平常说的多态一般…...
汽车及零配件企业海量文件数据如何管
汽车行业特点 汽车行业是工业企业皇冠上的一颗明珠,在国民经济中占据着举足轻重的地位。汽车行业具备技术密集、创新速度快、供应链复杂等特点,具体体现为: 技术密集:汽车行业是技术密集型行业,覆盖机械、电子、软件、…...
【AI学习】Mamba学习(十二):深入理解S4模型
#1024程序员节|征文# HiPPO的学习暂告一段落,按照“HiPPO->S4->Mamba 演化历程”,接着学习S4。 S4对应的论文:《Efficiently Modeling Long Sequences with Structured State Spaces》 文章链接:https://ar5iv…...
linux入门之必掌握知识点
#1024程序员节|征文# Linux基础 top命令详解 top命令是用来查看进程系统资源使用情况的工具,它可以动态的现实。 top命令执行后,按大写M可以按内存使用情况进行排序,大写P可以按CPU使用情况进行排序,大写H可以显示线…...
【Web.路由]——路由原理
这篇文章,我们来讲一讲什么是路由。 路由是 将用户请求地址映射为一个请求委托的过程,负责匹配传入的Http请求,然后将这些请求发送到应用的可执行终结点。 这里需要注意一个内容,发送到应用的可执行终结点。 路由的分类&#x…...
Spring Boot技术在中小企业设备管理中的应用
2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…...
Lua表(Table)
软考鸭微信小程序 过软考,来软考鸭! 提供软考免费软考讲解视频、题库、软考试题、软考模考、软考查分、软考咨询等服务 Lua中的表(table)是一种核心数据结构,它既是数组也是字典,能够存储多种类型的数据,包括数字、字符…...
51单片机应用开发(进阶)---外部中断(按键+数码管显示0-F)
实现目标 1、巩固数码管、外部中断知识 2、具体实现:按键K4(INT1)每按一次,数码管从0依次递增显示至F,再按则循环显示。 一、共阳数码管 1.1 共阳数码管结构 1.2 共阳数码管码表 共阳不带小数点0-F段码为ÿ…...
怎么区分主谓宾I love you与主系表I am fine? 去掉宾语看句子完整性 主系表结构则侧重于描述主语的状态、特征或性质
主谓宾与主系表是英语句子结构中的两种基本类型,它们在关注点、动词分类以及句子完整性方面有所区别。具体分析如下: 关注点 主谓宾I love you:主谓宾结构主要关注动作和影响对象之间的关系[1]。这种结构强调的是动态和行为,通常描…...
私域流量运营的误区
私域流量运营是近年来营销领域的重要趋势,但在实际操作中,很多企业和个人容易陷入一些误区。以下是几个常见的私域流量运营误区及其解决方法: 1. 只关注流量,不重视内容 误区:许多运营者认为,只要吸引到足…...
VirtualBox虚拟机桥接模式固定ip详解
VirtualBox虚拟机桥接模式固定ip详解 VirtualBox 桥接设置Ubuntu 24.04使用固定IP问题记录 VirtualBox 桥接设置 为什么设置桥接模式?桥接模式可以实现物理机和虚拟机互相通信,虚拟机也可以访问互联网(推荐万金油),物…...
面试问题基础记录24/10/24
面试问题基础记录24/10/24 问题一:LoRA是用在节省资源的场景下,那么LoRA具体是节省了内存带宽还是显存呢?问题二:假如用pytorch完成一个分类任务,那么具体的流程是怎么样的?问题三:详细介绍一下…...
中国区 Microsoft365主页链接请您参考:
Microsoft365主页链接请您参考: Redirecting PPAC链接请您参考: Power Platform admin center 关于Power Automate开启工单是在 https://portal.partner.microsoftonline.cn/Support/SupportOverview.aspx进行提交的。 对应所需对应管理员可以分配以下…...
Go encoding/json库
JSON在网络上广泛使用,是一种基于文本的数据传输方式。在本集中,我们将与 Daniel Marti 一起探索 Go 的 encoding/json 包和其他包。 本篇内容是根据2020年7月份[#141 {“encoding”:“json”}](https://changelog.com/gotime/141 “#141 {“encoding”…...
「实战应用」如何用图表控件LightningChart可视化天气数据?(二)
LightningChart.NET完全由GPU加速,并且性能经过优化,可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D,高级3D,Polar,Smith,3D饼/甜甜圈,地理地图和GIS图表以及适用于科学…...
苹果瑕疵数据集苹果质量数据集YOLO格式VOC格式 深度学习 目标检测 数据集
一、数据集概述 数据集名称:2类苹果图像数据集 数据集包含两类样本:正常苹果和有瑕疵的苹果。正常苹果样本代表完好的苹果,而有瑕疵的苹果样本代表苹果表面可能存在的损伤、瑕疵或病害。每个样本都经过详细标记和描述,以便训练模…...
旧电脑安装Win11提示“这台电脑当前不满足windows11系统要求”,安装中断。怎么办?
前言 最近有很多小伙伴也获取了LTSC版本的Win11镜像,很大一部分小伙伴安装这个系统也是比较顺利的。 有顺利安装完成的,肯定也有安装不顺利的。这都是很正常的事情,毕竟这个镜像对电脑硬件要求还是挺高的。 有一部分小伙伴在安装Windows11 …...
深入理解QT多线程编程
文章目录 多线程用法QThread类QtConcurrent类QFutureSynchronizer类获取线程信息线程优先级获取线程状态线程局部存储使用线程池监听线程事件Qt是一个跨平台的应用程序开发框架,广泛应用于图形用户界面(GUI)开发。它提供了强大的多线程支持,允许开发者在应用程序中创建和管理…...
React四官方文档总结一UI与交互
代码下载 React官网已经都是函数式组件文档,没有类组件文档,但是还是支持类组件这种写法。 UI 描述 组件 组件 是 React 的核心概念之一,它们是构建用户界面(UI)的基础。React 允许你将标签、CSS 和 JavaScript 组…...
如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系
文章目录 一、什么是 HTTP?无状态的含义 二、为什么 HTTP 是无状态的?三、Cookie 和 Session 的引入1. Cookie特点:示例: 2. Session特点:示例(Java Servlet): 四、HTTP、Cookie 和 …...
OpenCV视觉分析之运动分析(2)背景减除类:BackgroundSubtractorKNN的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 K-最近邻(K-nearest neighbours, KNN)基于的背景/前景分割算法。 该类实现了如 319中所述的 K-最近邻背景减除。如果前景…...
android黑屏问题记录
近期出现了一个黑屏问题: 仪表显示,主副屏黑的 :原因背光开启太晚,导致拍照时候是黑的,太晚的原因是绘制进程出现异常导致重启延后了时间,绘制进程crash原因是hwc调用底层库卡住,需更新hwc对应的…...
SIP 业务举例之 Call Forwarding - No Answer(无应答呼叫转移)
目录 1. Call Forwarding - No Answer 简介 2. RFC5359 的 Call Forwarding - No Answer 信令流程 呼转开始 呼转完成 3. Call Forwording - No Answer 过程总结 博主wx:yuanlai45_csdn 博主qq:2777137742 想要 深入学习 5GC IMS 等通信知识(加入 51学通信),或者想要 …...
EFCore pgsql Join 查询
安装包 > Microsoft.EntityFrameworkCore 6.0.35 6.0.35> Microsoft.EntityFrameworkCore.Tools 6.0.35 6.0.35> Npgsql.EntityFrameworkCore.PostgreSQL 6.0.29 6.0.29定义实体等 using Microsoft.EntityFrameworkCore; using Micros…...
力扣80:删除有序数组中重复项
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 示例 1&a…...
等保测评:安全计算环境的详细讲解
安全计算环境是信息安全领域中的一个重要概念,旨在确保在计算过程中数据的机密性、完整性和可用性。随着信息技术的迅猛发展和网络攻击的日益频繁,构建安全计算环境显得尤为重要。本文将详细探讨安全计算环境的主要组成部分、特性及其在信息安全中的作用…...
[Java基础] Lambda 表达式
往期回顾 [Java基础] 基本数据类型 [Java基础] 运算符 [Java基础] 流程控制 [Java基础] 面向对象编程 [Java基础] 集合框架 [Java基础] 输入输出流 [Java基础] 异常处理机制 [Java基础] Lambda 表达式 目录 概述 Lambda 表达式的基本语法 应用场景 并发编程 集合…...
《深入掌握高德地图 API:全面调用指南与最佳实践》
本文 高德地图 API 调用指南引言高德 API 的基础设置注册和获取 API Key 基本 API 调用结构地理编码与逆地理编码地理编码(Geocoding)逆地理编码(Reverse Geocoding)注意事项 路径规划(Direction API)驾车路…...
【功能安全】系统架构设计
目录 01 系统架构介绍 02 投票逻辑架构介绍 03 SIS架构 04 ADS域控制器架构设计 01 系统架构介绍 法规GBT 34590 Part4 part10定义的软件要求、设计和测试子阶段之间的关系(其中的3-7个人建议翻译为初始架构设计更合理 ) 系统架构的作用…...
FPGA实现PCIE视频采集转USB3.0输出,基于XDMA+FT601架构,提供3套工程源码和技术支持
目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的PCIE方案本博已有的USB通信方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图电脑端视频PCIE视频采集QT上位机XDMA配置及使用XDMA中断模块FDMA图像缓存FT601功能和硬件电路FT601读时序解读FT601写时序解读U…...
湖南省做网站的/乐天seo视频教程
explicit关键字 explicit用途: 防止利用隐式类型转换方式来构造对象#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std;class MyString {public:MyString(char...
wordpress 用户 权限/百度收录申请入口
1、系统管理1.1 连接MySQL格式: mysql -h主机地址 -u用户名 -p用户密码举例:例1:连接到本机上的MySQL。首先在打开DOS窗口,然后进入目录 mysqlbin,再键入命令"mysql –u root –p",回…...
帮人做网站怎么收费/地推团队如何收费
商人的诀窍 Description E_star和von是中国赫赫有名的两位商人,俗话说的好无商不奸,最近E_star需要进一批苹果。可是他需要的苹果只有von才有,von的苹果都存在他的传说中很牛叉的仓库里,每个仓库都存了不同种类的苹果,…...
管理咨询公司项目运作流程图/宁波seo高级方法
问题:在SQL服务器上用sa账号登陆后执行SELECT * FROM OpenDataSource( Microsoft.Jet.OLEDB.4.0,Data Source"d:\a.xls";User IDAdmin;Password;Extended propertiesExcel 8.0)...[Sheet1$] 提示:链接服务器"(null)"的 OLE DB 访问接…...
做网站需要注意什么问题/新闻式软文
C语言程序设计(第七章 指针) 一、指针是什么 由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化地称为“指针”。意思就是通过它能找到以它为地址的内存单元。 假如有输入语句&#…...
惠城发布最新通知/长沙排名优化公司
这篇文章很好,多网卡推荐用第四种方法。在使用双网卡,同时使用2个网关的时候就需要加一条静态路由了。当然还有很多时候会需要加路由。操作系统版本centos-6.4 64bit一:使用route 命令添加1、使用route 命令添加的路由,机器重启或…...