c++中函数的c++奇偶数判断性要怎么实现

C++的 多态面向对象有三个基本特征:封装、继承、多态。其中,封装可以使得代码模块化,忽略或者隐藏实现细节,优化整个程序的结构;继承可以扩展已存在的代码模块(类),避免重复造轮子;而多态则是为了实现接口的重复使用。这里我们着重学习多态的概念,使用和其实现的原理。什么是多态?同一个方法在派生类和基类中的行为是不同的。换句话说,方法的行为应取决于调用该方法的对象。这种复杂的行为称为多态—具有多种形态,就是指同一个方法的行为将随环境而异。和多态相关联概念虚函数:用virtual关键字申明的函数纯虚函数:虚函数再加上 = 0;如:virtual void fun()=0;即抽象类!必须在派生类实现内容虚表:存在虚函数的类都有一个一维的虚函数表称之为虚表虚表指针:类的对象有一个指向虚表开始的指针称之为虚表指针函数名联编(binding):将源代码中的函数调用解释为可执行特定的函数代码块被称为函数名联编。静态联编(早期联编,early binding):编译器在编译过程中,查看函数参数以及函数名确定调用的函数,这种联编称为静态联编又称早起联编。动态联编(晚期联编,late binding):相对静态联编,编译器在程序运行时选择正确的虚拟方法的代码,这种动态联编,又称晚期联编。动态联编能够重新定义类的方法,而静态联编在这方面很差。那为什么不摒弃静态联编呢?是效率和概念模型的需求。静态联编有调用速度快,效率高的优点。另一方面,在设计时,可能包含一些不在派生类重新定义的成员函数,以提高效率或者明确不需要在派生类中重新定义。向上强制转换:将派生类强制引用或指针转换为基类的引用或指针被称为向上强制转换(upcasting),这是共有继承不需要进行显示类型转换,是is-a规则。向下强制转换:将基类指针或引用转换为派生类指针或引用称之为向下强制转换(downcasting)。必须使用显示的转换。以上是多态使用中会涉及到的一些概念。多态从实现上的分类多态从实现的角度可以分为两类:编译时的多态和运行时的多态。编译时的多态(静态多态)是在静态联编阶段,通过函数重载和模板实现的。利用函数重载机制,在调用同名函数时,编译器会根据实参的具体情况确定要调用的是哪个函数。运行时的多态(动态多态)是用动态联编阶段,通过虚函数来实现。动态多态使用的两个条件:1、类的定义时存在继承关系,存在虚机制,派生类重写虚函数2、 隐式向上强制转换使基类指针或引用可以指向基类对象或者派生类对象,这里需要动态联编,在运行时,根据不同的环境,产生不同的行为。多态使用实例下面我们通过实例来看一下多态的使用/*
C++多态测试实例
*/
#include <string>
#include <iostream>
using namespace std;
//基类
class Base {
public:
virtual void vfunc1()
{
printf("Base::vfunc1\r\n");
}
virtual void vfunc2()
{
printf("Base::vfunc2\r\n");
}
virtual void vfunc3()
{
printf("Base::vfunc3\r\n");
}
virtual void vfunc4()
{
printf("Base::vfunc4\r\n");
}
void func1()
{
printf("Base::func1\r\n");
}
void func2()
{
printf("Base::func2\r\n");
}
private:
int m_data1, m_data2;
};
//派生类A
class A: public Base {
public:
virtual void vfunc1()
{
printf("A::vfunc1\r\n");
}
void func1(int a)
{
printf("A::func1 with %d\r\n",a);
}
void func1()
{
printf("A::func1\r\n");
}
private:
int m_data3;
};
//派生类B
class B : public Base {
public:
virtual void vfunc1()
{
printf("B::vfunc1\r\n");
}
virtual void vfunc3()
{
printf("B::vfunc3\r\n");
}
void func2()
{
printf("B::func2\r\n");
}
private:
int m_data1, m_data4;
};
int main()
{
//静态联编调用
A object_a;
object_a.vfunc1();
//调用A类虚函数vfunc1
object_a.vfunc2();
//调用A类未重写vfunc2,调用继承基类虚函数vfunc2
object_a.func1();
//调用A类调用方法func1
object_a.func1(100);
//调用A类调用重载方法func1,实现静态多态
//动态联编调用,实现动态多态
B object_b;
Base* p = &object_a;
//隐式向下转换基类指针p 指向类A对象object_a
p->vfunc1();
//基类指针指向对象A,调用A类虚函数vfunc1
p = &object_b;
//隐式向下转换基类指针p 指向类B对象object_b
p->vfunc1();
//基类指针指向对象B,调用B类虚函数vfunc1
system("pause");
}
运行结果:如上面代码和注释所示,实现了静态多态和动态多态。动态多态实现原理动态多态是如何实现的?运行时的动态联编到底做了什么?带着问题,我们首先改造一下上面的实例。在实例中复制一个Base类,命名为BaseWithoutV,将BaseWithoutV类中的虚函数关键字都去掉,其他保持不变。我们来看看这两个类的size。代码如下:/*
C++多态测试实例
*/
#include <string>
#include <iostream>
using namespace std;
//基类
class Base {
public:
virtual void vfunc1()
{
printf("Base::vfunc1\r\n");
}
virtual void vfunc2()
{
printf("Base::vfunc2\r\n");
}
virtual void vfunc3()
{
printf("Base::vfunc3\r\n");
}
virtual void vfunc4()
{
printf("Base::vfunc4\r\n");
}
void func1()
{
printf("Base::func1\r\n");
}
void func2()
{
printf("Base::func2\r\n");
}
private:
int m_data1, m_data2;
};
//无虚函数的基类
class BaseWithoutV {
public:
void vfunc1()
{
printf("BaseWithoutV::vfunc1\r\n");
}
void vfunc2()
{
printf("BaseWithoutV::vfunc2\r\n");
}
void vfunc3()
{
printf("BaseWithoutV::vfunc3\r\n");
}
void vfunc4()
{
printf("BaseWithoutV::vfunc4\r\n");
}
void func1()
{
printf("BaseWithoutV::func1\r\n");
}
void func2()
{
printf("BaseWithoutV::func2\r\n");
}
private:
int m_data1, m_data2;
};
//派生类A
class A: public Base {
public:
virtual void vfunc1()
{
printf("A::vfunc1\r\n");
}
void func1(int a)
{
printf("A::func1 with %d\r\n",a);
}
void func1()
{
printf("A::func1\r\n");
}
private:
int m_data3;
};
//派生类B
class B : public Base {
public:
virtual void vfunc1()
{
printf("B::vfunc1\r\n");
}
virtual void vfunc3()
{
printf("B::vfunc3\r\n");
}
void func2()
{
printf("B::func2\r\n");
}
private:
int m_data1, m_data4;
};
int main()
{
printf("Base size is
= %d\r\n", sizeof(Base));
printf("BaseWithoutV size is
= %d\r\n", sizeof(BaseWithoutV));
Base base;
BaseWithoutV baseWithoutV;
//静态联编调用
A object_a;
object_a.vfunc1();
//调用A类虚函数vfunc1
object_a.vfunc2();
//调用A类未重写vfunc2,调用继承基类虚函数vfunc2
object_a.func1();
//调用A类调用方法func1
object_a.func1(100);
//调用A类调用重载方法func1,实现静态多态
//动态联编调用,实现动态多态
B object_b;
Base* p = &object_a;
//隐式向下转换基类指针p 指向类A对象object_a
p->vfunc1();
//基类指针指向对象A,调用A类虚函数vfunc1
p = &object_b;
//隐式向下转换基类指针p 指向类B对象object_b
p->vfunc1();
//基类指针指向对象B,调用B类虚函数vfunc1
system("pause");
}
运行结果:我们看到含有虚函数的Base类比没有虚函数的BaseWithoutV多了4个字节(32位程序)。多了什么?通过调试程序,如上图,忽略成员变量,我们发现含有虚函数的基类多了一个虚函数表指针。C++规定了虚拟函数的行为,但将实现交给了编译器处理。通常,编译器处理虚函数的方法是:给每一个对象添加一个隐藏的成员—虚函数表指针。动态多态就是通过虚函数和虚函数表来实现的。凡是含有虚函数的类的对象内部就会有指向类内部的虚表指针。通过这个指针索引虚函数。虚函数的调用会被编译器根据环境动态的转换为对虚函数表的访问,类似如下过程:base->vfunc(); //ptr代表this指针,vfunc是虚函数*(ptr->__vfptr[虚函数索引])(ptr);知道了这个原理,我们再来看看实力中动态多态的使用。
//动态联编调用,实现动态多态
A object_a;

B object_b;
Base* p = &object_a;
//隐式向下转换基类指针p 指向类A对象object_a
p->vfunc1();
//基类指针指向对象A,调用A类虚函数vfunc1
p = &object_b;
//隐式向下转换基类指针p 指向类B对象object_b
p->vfunc1();
//基类指针指向对象B,调用B类虚函数vfunc1
运行结果:定义的基类Base指针p,分别向下强制转换指向派生A类和B类,实现了对A,B类中虚函数vfunc1()的分别调用。这样就实现了不同对象去完成同一行为时,展现出不同的形态。p指向A类时:p指向B类时:程序运行调用虚函数时,程序将查看存储在对象中的虚函数表指针,然后转向相应的函数地址表,索引到调用函数执行。从调用过程中可以看到,使用虚函数时,在内存和执行速度方面有一定的成本包括:每个对象增加存储地址的空间对每个类,编译器都要创建一个虚拟函数地址表每个函数的调用都需要执行一步额外的操作,即到表中查找函数地址这也印证了上面我们提到的静态联编相对于动态联编效率高的优点。虚函数在汇编中又是怎么个样子呢?我会在另一片文章中说明。欢迎进QQ群,一起学习交流。群名称:移动安全群号码:205988195群暗号:OK哥}

选择擅长的领域继续答题?
{@each tagList as item}
${item.tagName}
{@/each}
手机回答更方便,互动更有趣,下载APP
提交成功是否继续回答问题?
手机回答更方便,互动更有趣,下载APP
展开全部首先求函数定义域,看定义域是否关于原点对称,不对称则非奇非偶,若定义域关于原点对称了,再看f(-x)=什么,等于f(x)就是偶函数,等于-f(x)就是奇函数。数学:数学是研究数量、结构、变化、空间以及信息等概念的一门学科。数学是人类对事物的抽象结构与模式进行严格描述的一种通用手段,可以应用于现实世界的任何问题,所有的数学对象本质上都是人为定义的。从这个意义上,数学属于形式科学,而不是自然科学。不同的数学家和哲学家对数学的确切范围和定义有一系列的看法。已赞过已踩过你对这个回答的评价是?评论
收起
展开全部
第一步:先求定义域(因为只有定义域满足关于原点对称才有可能谈奇偶性)对x+√(1+x^2)当x≥0时,显然满足x+√(1+x^2)>0当x<0时原式=-√(x平方)+√(1+x^2)>0第二步:求f(-x)(因为不论是奇是偶都要用到与它的比较)设y=f(x)则f(-x)=ln[x+√(1+x^2)] 显然不是偶函数又 -f(x)=-ln[x+√(1+x^2)] =ln{[x+√(1+x^2)]的-1次方}=……=f(-x)所以原函数是一个奇函数-ln[x+√(1+x^2)] =ln{[x+√(1+x^2)]的-1次方}就是前面的系数实际上可以换成对数的指数随后分母有理化
本回答被提问者采纳
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
为你推荐:
下载百度知道APP,抢鲜体验使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。扫描二维码下载
×个人、企业类侵权投诉
违法有害信息,请在下方选择后提交
类别色情低俗
涉嫌违法犯罪
时政信息不实
垃圾广告
低质灌水
我们会通过消息、邮箱等方式尽快将举报结果通知您。说明
做任务开宝箱累计完成0
个任务
10任务
50任务
100任务
200任务
任务列表加载中...
}

我要回帖

更多关于 c++奇偶数判断 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信