简单继承的例子: #include <iostream> #include <string> using namespace std; class CStudent { private: string name; string id; //学号 char gender; //性别,'F'代表女, 'M'代表男 int age; public: void PrintInfo(); void SetInfo( const string & name_,const string…
面向对象的程序设计方法 抽象:将某类客观事物共同特点(属性)归纳出来,形成一个数据结构(可以用多个变量描述事物的属性):将这类事物所能进行的行为也归纳出来,形成一个个函数,这些函数可以用来操作数据结构. 封装:通过某种语法形式,将数据结构和操作该数据结构的函数“捆绑”在一起,形成一个“ 类”,从而使得数据结构和操作该数据结构的算法呈现出显而易见的紧密关系. 从客观事物抽象出类 写一个程序,输入矩形的长和宽,输出面积和周长. 比如对于“矩形”这种东西,要用一个类来表示,该如何做“抽象”呢?矩形的属…
形式 返回值类型 operator 运算符(形参表) { …… } 运算符重载 (1)运算符重载的实质是函数重载(2)可以重载为普通函数,也可以重载为成员函数 class Complex { public: double real,imag; Complex( double r = 0.0, double i= 0.0 ):real(r),imag(i) { } Complex operator-(const Complex & c); }; Complex operator+( const C…
1.1继承与多态的基本概念 1.1.1 继承和多态 继承是面向对象程序设计的主要特征之一,允许重用现有类(基类,亦称超类.父类)去创建新类(子类,亦称派生类)的过程.子类将获取基类的所有非私有数据和行为,可以定义其他数据和行为. 派生类具有基类所有非私有数据和行为以及新类自己定义的所有其他数据或行为,即子类具有两个有效类型:子类的类型和它继承的基类的类型. 对象可以表示多个类型的能力称为多态性. 多态性示例. public class Parent { public Parent() { } p…
游戏软件的开发最能体现面向对象设计方法的优势.游戏中的人物.道具.建筑物.场景等都是很直观的对象,游戏运行的过程就是这些对象相互作用的过程.每个对象都有自己的属性和方法,不同对象也可能有共同的属性和方法,特别适合使用继承.多态等面向对象的机制.下面就以“魔法门”游戏为例来说明多态在增加程序可扩展性方面的作用. “魔法门”游戏中有各种各样的怪物,如骑士.天使.狼.鬼,等等.每个怪物都有生命力.攻击力这两种属性.怪物能够相互攻击.一个怪物攻击另一个怪物时,被攻击者会受伤:同时被攻击者会反击,使得攻击…
在c++中,类和类之间有两种基本关系:复合关系和继承关系. 复合关系也称为“has a”关系或“有”的关系,表现为封闭类,即一个类以另一个类的对象作为成员变量. 继承关系也称为“is a”关系或“是”关系,即派生类对象也是一个基类对象. 在设计两个有关系的类时要注意,并非两个类有共同点,就可以让它们成为继承关系.让类B继承类A,必须满足“类B所代表的事物也是类A所代表的事物”这个命题从逻辑上是成立的.例如:写一个平面上的点类point: class CPoint{ double x,y; };…
假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类.狗是有主人的,主人也有狗.假定狗只有一个主人,但一个主人可以有最多10条狗.该如何处理“主人”类和“狗”类的关系呢?下面是一种直观的写法: #include<iostream> using namespace std; class CDog; class CMaster { CDog dogs[10]; int dog_num; }; class CDog { CMaster m; }; int main() { }…
类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespace std; class CBase { public: void func1() { func2(); } virtual void func2(){cout<<"CBase::func2()"<<endl;} }; class CDerived:public…
“多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespace std; class A{ public: int i; virtual void func(){}; virtual void func2(){}; //如果为只有一个去掉 virtual 关键字即virtual void func2(){};变为 void func2(){}; 输出结果不变 仍为 8…
1.当用一个对象去初始化同类的另一个对象时,会引发复制构造函数被调用.例如,下面的两条语句都会引发复制构造函数的调用,用以初始化c2. C c2 (c1); C c2=c1; 这两条语句是等价的.注意第二条是初始化语句,不是赋值语句.赋值语句的等号左边是一个早已有定义的变量,赋值语句不会引发复制构造函数的调用.例如: C c1,c2; c1=c2; "c1=c2;"这条语句不会引发复制构造函数的调用,因为c1早已生成,已经初始化过了. 2.如果函数F的参数是类C的对象,那么当F被调用时…
示例1: #include<iostream> using namespace std; class CDemo{ public: ~CDemo(){cout<<"destructor"<<endl;} }; void Func(CDemo obj){ cout<<"func"<<endl; } CDemo d1; CDemo Test(){ cout<<"test"<…
类型转换构造函数:  除复制构造函数外,只有一个参数的构造函数一般可以称作类型转换构造函数,因为这样的构造函数能起到类型自动转换的作用.例如下面的程序: #include<iostream> using namespace std; class Complex{ public: double real,imag; Complex(int i){ cout<<"IntConstructor called"<<endl; real=i;imag=0; }…
背景:   c++是在c语言的基础上发展而来的,第一个c++的编译器实际上是将c++程序翻译成c语言程序,然后再用c语言编译器进行编译.c语言没有类的概念,只有结构,函数都是全局函数,没有成员函数.翻译时,将class翻译成struct.对象翻译成结构变量是显而易见的,但是对类的成员函数应该如何翻译?对“my.modify();”这样通过一个对象调用成员函数的语句,又该如何翻译呢? c语言只有全局函数,因此成员函数只能被翻译成全局函数:“my.modify();”这样的语句也只能翻译成普通的调用…
#include<iostream> using namespace std; class A; class B{ public: void f(A* pt){}; } class A{ public: void f(B *pt){} } 第3行声明了A类,A类的定义在后面,之所以要提前声明,是因为B类的定义中用到了A类型(第6行),而此时A类还没有定义,编译会报错.不要第三行,而把A类的定义写在B类前面,是解决不了这个问题的,因为A类中也用到了B类(第10行),把A类的定义写在前面会导致第1…
  封闭类:  一个类的成员变量如果是另一个类的对象,就称之为“成员对象”.包含成员对象的类叫封闭类. #include<iostream> using namespace std; class A{ int n; public: A(int n):n(n){} }; class B{ A t; int g; public: B(int n,int g):t(n),g(g){} }; B是一个封闭类,生成封闭类对象的语句一定要让编译器能够弄明白其成员对象的是如何初始化的,否则就会编译错误. 封…
定义: string类是STL中basic_string模板实例化得到的模板类.其定义如下: typedef basic_string<char>string; 构造函数: string类有多个构造函数,但没有接收一个整型参数或一个字符型参数的构造函数 string s1(); //s1="" string s2("hello"); //s2="hello" string s3(4,'k'); //s3="kkkk"…
背景: 数组的长度是定义好的,在整个程序中固定不变.c++不允许定义元素个数不确定的数组.例如: int n; int a[n]; //这种定义是不允许的 但是在实际编程中,往往会出现要处理的数据数量在编程时无法确定的情况.如果总是定义一个尽可能大的数组,又会造成空间浪费.何况,这个“尽可能大”到底应该多大才够呢? 为了解决这个问题,c++提供了一种“动态分配内存”的机制,使得程序可以在运行期间,根据实际需要,要求操作系统临时分配一片内存空间用于存放数据.这种内存分配是在程序运行中进行的,而不是…
背景: 使用函数能够避免将相同代码重些多次的烦恼,还能减少可执行程序的体积,但也会带来程序运行时间上的开销.函数调用在执行时,首先在栈中为形参和局部变量分配存储空间,然后还要将实参的值复制给形参,接下来还要将函数的返回地址(改地址指明了函数执行结束后,程序应该回到哪里继续执行)放入栈中,最后才跳转到函数内部执行.这个过程是要耗费时间的.另外,函数执行return语句返回时,需要从栈中回收形参和局部变量占用的存储空间,然后从栈中取出返回地址,再跳转到该地址继续执行,这个过程也要耗费时间.总之,使用…
JavaScript 面向对象程序设计(下)--继承与多态 前面我们讨论了如何在 JavaScript 语言中实现对私有实例成员.公有实例成员.私有静态成员.公有静态成员和静态类的封装.这次我们来讨论一下面向对象程序设计中的另外两个要素:继承与多态. 1 又是几个基本概念 为什么要说又呢? 在讨论继承时,我们已经列出了一些基本概念了,那些概念是跟封装密切相关的概念,今天我们要讨论的基本概念,主要是跟继承与多态相关的,但是它们跟封装也有一些联系. 1.1 定义和赋值 变量定义是指用 var a;…
1.结构化程序设计的不足 程序=算法+数据结构 数据结构和变量相对应,算法和函数相对应,算法是用来操作数据结构的. 结构化程序设计中,函数和其所操作的数据结构,没有直观的联系.随着程序规模的增加,程序逐渐难以理解,很难一下子看出来:某个数据结构到底有哪些函数可以对它进行操作?某个函数到底是用来操作哪些数据结构的?任何两个函数之间存在怎样的调用关系? 结构化程序设计没有"封装"和"隐藏"的概念. 要访问某个数据结构中的某个变量,就可以直接访问,那么当该变量的定义有改动…
字符类型 #include <iostream> using namespace std; int main() { cout << << endl; cout << static_cast<) << endl; ; } 运行结果: 注意类型转换 再谈auto 1.在使用auto自动推断变量类型时,没有必要采用列表初始化“{}”的方式,而是直接用“=”就好了 2.在较小的作用域中建议优先使用auto template<class T&…
读书笔记,写的很乱   事件处理程序   事件处理程序分为三种: 1.html事件2. DOM0级,3,DOM2级别  没有DOM1 同样的事件 DOM0会顶掉html事件   因为他们都是属性  而DOM0比html事件执行的晚(可以理解为谁离html元素近先执行谁) JS事件执行顺序理解 先捕获(document-往下)->目标阶段(执行)->冒泡(具体到不具体); addEventListener 第三个参数 默认false   (false 是冒泡阶段执行)   true 是捕获阶段执…
内容: (1)子类中的拷贝构造和拷贝赋值 (2)多继承和虚继承 (3)多态的初识 (4)虚析构的特性和使用 (5)多态的底层实现 (6)纯虚函数.抽象类的概念 1.子类中的拷贝构造和拷贝赋值 子类中的拷贝构造和拷贝赋值可能也需要显式的指定父类子对象的拷贝构造和拷贝赋值的方式 2.多继承和虚继承2.1 格式: class 子类名 : 继承方式 父类名1,继承方式 父类名2,... { //子类中的属性和行为 }; 如: 员工类 / \销售员工类 管理者类 \ / 销售管理类 叫做:钻石继承 2.2…
一.对象与类 类:类是一个模版,它描述了一类对象的行为和状态. class animal { private int color; private int size; public void eat () { System.out.println("I'm eating!"); } public void sleep () { System.out.println("I'm sleeping!"); }}        上面一段代码就定义了一个animal类,它在内…
在学习和分析标准I/O库的同时, 可以重点与Linux的I/O系统调用进行比较. stdin. stdout和stderr都是FILE类型的文件指针, 是由C库静态定义的, 直接与文件描述符0. 1和2相关联, 所以应用程序可以直接使用它们.其中,stdin是不可写的, stdout是不可读的, 而stderr不仅不可读, 且没有缓存. I/O的缓存 C库的I/O接口对文件I/O进行了封装, 为了提高性能, 其引入了缓存机制, 共有三种缓存机制: 全缓存. 行缓存及无缓存. (1)全缓存一般用于…
1.原型链继承 让构造函数的原型对象等于另一个类型的实例,利用原型让一个引用类型继承另一个引用类型的属性和方法 function SuperType() { this.property=true; } SuperType.prototype.getSuperValue=function(){ return this.property; }; function SubType() { this.subProperty=false; } //继承SuperType SubType.prototype…
一.重载类型强制转换运算符 在C++中,类型的名字(包括类的名字)本身也是一种运算符,即类型强制转换运算符.类型强制转换运算符是单目运算符,也可以被重载,但只能重载为成员函数,不能重载为全局函数.经过适当重载后,“(类型名)对象”这个对对象进行类型强制转换的表达式就等价于“对象.operator类型名()”,即变成对运算符函数的调用. 下面的程序对double类型类型强制转换运算符进行了重载. #include <iostream> using namespace std; class Com…
实例:长度可变的整型数组类 int main() { //要编写可变长整型数组类,使之能如下使用: CArray a; //开始里的数组是空的 ; i < ; ++i) a.push_back(i);//->要用动态分配的内存来存放数组元素,需要一个指针成员变量 CArray a2, a3; a2 = a;//->要重载“=” ; i < a.length(); ++i) cout << a2[i] << " ";//->要重载“[…
友元 友元分为友元函数和友元类两种. 一.友元函数 在定义一个类的时候,可以把一些函数(包括全局函数和其它类的成员函数)声明为“友元”,这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对象的私有成员了. 将全局函数声明为友元的写法如下: friend返回值类型 函数名(参数表): 将其他类的成员函数声明为友元的写法入下: friend返回值类型 其他类的类名::成员函数名(参数表): 但是,不能把其他类的私有成员函数声明为友元. #include<iostream> using…
1.内联函数(inline关键字) eg.inline int Max(int a,int b) { if(a>b) return a; return b; } 当编译器处理调用内联函数的语句时,直接将整个函数体的代码插入调用语句处,但是会使最终可执行程序的体积增加.(这是以空间换时间) 2.函数的重载(使函数命名变得简单) (1)定义:一个或多个函数,名字相同,然而参数个数或类型不同 (2)编译器判断形式:根据函数调用语句中实参的个数和类型来判断 eg. int MAX(int a,int b…