Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1437395
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2253
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-11 22:27
个人简介

--

文章分类

全部博文(241)

文章存档

2021年(3)

2019年(6)

2018年(1)

2017年(9)

2016年(21)

2015年(50)

2014年(125)

2013年(26)

我的朋友

分类: C/C++

2014-01-09 22:22:48

Class ClassName

{

Private:

Int a,b,c;

Public:

Void set(int a,int b,int c);

Void fun();

};

若成员函数很短,可以直接在内部定义,单位了清晰,还是外面定义。

若很短,外部定义为内联函数效果一样。

Inline void ClassName::set(....)

{..................}

 

如果只对对象读操作,通常定义为const成员函数,可以让别人清晰看到不会改变对象值。而且,能够作为const的尽量写为constVoid print() const;

 

重载:函数名称相同,但是参数类型与个数、返回值不同

操作符重载:

Class **

{

Point operator+(const Point& a, const Point& b);

}

Point  Point::operator+const Point& a, const Point& b

{

Point s;

S.set(a.x + b.x, a.y + b.y);

Return s;

}

调用:operator+(a,b)  Point

::  、 。 。?: sizeof  typedef都不可以重载。

 

**.h

#ifndef HEAD_H

#define HEAD_H 

Class A

{

........

};

#endif

**.cpp

#include “**.h”

#include 

Using namespace std;

成员函数定义

 

静态成员:全局数据区,所有对象共有。作为共有很危险

静态成员函数:静态成员私有,静态成员函数可以不捆绑对象的调用访问静态成员,且只能访问静态成员,不能访问类的其他成员。但是可以通过传递对象指针访问对象变量。

静态成员变量className::num = 0; 

 

Frind函数,类定义中直接声明为friend,相应其他类可以直接调用

该函数声明:friend 类名 函数名()

 

构造函数:

和类同名,无返回值。同样可以通过set()实现,但是多了步骤

初始化简单做法:constructstring name = “noName”){  Name = name;  }

成员列表:Student(string n = “noName”, int ssID=0):id(ssID),name(n){......}

 

一次性对象:无名对象,多在参数传递时用到。

 

局部对象初始化:根据运行对象的顺序决定对象创建的顺序,静态对象只创建一次。

全局对象初始化:main之前就已经初始化成功,出错很难定位,方法可以先局部后全局,或是打印出来。

 

全局对象,在**.h中定义Student stu(18);   在另外一个文件中应用

Extern Student stuTutor tur(stu).,会出现因为编译器原因导致对象创建顺序不一样,所以避免设置全局对象。,这是程序设计重用及安全的要诀。更不要让全局对象之间相互依赖。

 

类中组合多个类对象,不是按照构造顺序,而是按照定义顺序。

析构顺序正好与构造顺序相反。

拷贝构造函数:Person  A(“aa”);  Person B = A; 深拷贝,均构造析构

Person B(A); 浅拷贝,仅仅只是个指针,构造一次。可以使用自定义拷贝构造函数。尽量使用引用传递,且尽量使用常量引用传递。

 

浅拷贝:对象本体与对象实体一致。

深拷贝:对象本体与对象实体不一致。

深拷贝需要动态内存分配。本体释放时需要释放内存。析构函数来完成。

深拷贝需要重载运算符:P2 = P1//  Person P1(“dsadf”);.

Person &operator=(Person& s)

{

If(this == &s) return s;

Delete [] name;

Name = new char[strlen(s.name)+1];

If (Name)

{

Strncpy(Name, s.name,strlen(s.name));

Retunr *this;

}

}

一旦重构运算符、深拷贝,说明申请了内存,则需要析构函数,将申请内存释放掉。

 

继承:

Class B: public BaseClass

{

....// 派生类对象总是含有基类对象。具体空间安排的前后顺序不定。

}

 

保护成员与私有成员,不能被我们公共访问,可被类内部的成员函数访问。

子类可以访问父类的protected成员、函数,但是其他类就不行。

 

派生类默认无参构造函数,首先调用父类构造函数,若父类定义含参构造函数则会出现问题。

修改数据的权限:一般该成员在父类中也是可见的,private派生类 public : using Base:: data;

 

继承与组合:物理结构上都是包含关系,但是性质上完全不同。

组合:类中含有对象成员的情形。

采用继承还是组合,首先从两个类对象的性质分,性质相同则一个类拥有另一个类大部分操作;若都太抽象分不清,如果操作多共同则用继承会好些。组合则职责分明,麻烦点但是调试直接明了。

 

多重继承:

Class A {。。。}; class B{...};

Class C:public A, public B {...};

C继承了AB相同的成员、方法,如何区分出来到底是谁的成员、方法,导致基类成员的名称冲突。通过C.A::**;或是C.B:**

 

多重继承几个子类继承自相同子类,会出现含义不清晰的现象。

所以希望可以有根本的基类只有一个副本,则子类共享该基类的所有成员与方法。(菱形继承关系),用到就是虚拟继承。

Class Base {...};  class A:virtual public Base {........};  Class B:virtual public Base {.......};

Class C:public A,public B {...构造需要调用A() B()构造...};

多重继承,调试、模糊性问题尽量少用多重继承。一些多重继承功能强大的库多用来组合使用,用户很少继承。

 

多态

Void fun(student &x)//根据是对象类型判断:本科生还是研究生,执行相应扣费操作。多个状态。

若只支持继承但不支持多态,则不能称作支持面向对象编程。

C++通过虚函数实现多态。

Class Base {   virtual void display();  };  class A : public Base { virtual void dispaly() ; };

Void fun (Base &x) {..x.dispaly();.}   

一旦声明为虚函数,以后继承的同名函数均为虚函数。

包含虚函数的对象存在一个虚函数指针指向虚函数列表,编译器滞后处理,运行时根绝数据类型执行相应的虚函数。

 

虚函数必须是父子类之间所有参数、返回值均要完全一致,而不是重载。但是返回是父子类型的对象则另当别论,出现多态操作。

 

静态成员函数不能为虚函数,不受对象捆绑,也就失去多态意义。内联函数不能为虚函数(内联函数不能再运行中动态确定位置,虚函数在类中定义也视为非内联)。

构造函数不能为虚函数,析构函数可以并通常是虚函数。析构有些指向基类,有些事子类,针对不同对象类型执行不同操作。

 

减少冗余代码:按层次建立类关系,拥有共同的很小基类,将需要根据子类类型不同执行不同操作的接口定义为虚函数。

 

类型转换:

Dynamic_cast:专门针对有虚函数的继承结构来的,将基类指针转换为想要的子类指针。

Static_cast:范围更广的转换,必须是相关类型。

Const_cast:常量转型,其他类型可以转为const类型,但是const转为非const不行。

例:GraduateStudet gs(“smith”);

Student* ps = static_cast &gs; GraduateStudent *pGs = static_cast ps;

若两类无关,而又不失void指针,则不可以转换,转后变为0

 

抽象类:

抽象类专门用来被继承,天生用来当爹的,不能创建对象。抽象类不应该有构造函数。

抽象类至少定义一个纯虚函数(不具体实现的虚函数),专门为子类多态留下的接口。

纯虚函数定义:virtual void fun() = 0;,

只要是子类还有没覆盖的纯虚函数,则该子类仍可以作为抽象类被继承并覆盖抽象类。

 

可扩展性:class Bpublic A{Virtual newFun();}  其中A为原先实现的功能,扩展新功能。

 

模板:

函数模板:

Template // 

返回类型 函数模板名(数据参数表)

{

函数模板定义体。

}

注意:类型匹配非常严格,如果类型不一致就会编译错误,必须精确匹配。

类模板:

Template

Struct Node

{

Node(T& d):data(d),next(0),pref(0){}

T data;  Node *next, *pref;

}

Template

Class List

{

Node *first,last;

Public:

List();

Void add(T& data);

Void remove(T& data);

Node* find(T& head);

Void print();

~List();

}

Template

Void List::add(T& data){........}

模板类:template List< int>; List dList;

组织形式:模板定义与模板使用在同一个便宜单位中,一般将模板定义与实现都在头文件中。

或者将模板定义与实现分开,头文件是定义,源文件为实现方法。(需要加export

 

模板的多态:多态通过虚函数实现,动多态。

函数模板实现多态:编译时刻进行静态识别,静多态。

Template

Void fun(T& a){ .....  }

动多态:类层次结构,基类必须为多态类,含有虚函数等,多态函数单独在外面实现。

静态类:适合于所有累,不需要虚函数。通过函数模板实现。

Java中都是动多态,虚函数实现。抽象编程动多态更好些,实现雨啊代码隐蔽无需提供给用户。性能上静多态优于动多态。静多编译前就知道,调试方便。

 

泛型编程://模板编程 ,STL就是基于模板的框架类库。


异常

C中全局变量errno,专门用于存放错误代码。

框定异常:try

定义异常:catch

抛掷异常:throw

 

阅读(691) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~