类的抽象与封装部分的小结与补充
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C++中类的 static 成员 static 属性要作为全局变量进行声明,表示一个类的全体对象所共有的数据 在一个程序中,同一个类的各个对象的 static 属性供用相同的存储空间 类的成员函数也可以声明为 static,static 成员函数中不允许访问类的非 static 成员
小问题:请指出下列程序中不符合语法的语句。 #include <cstdlib> #include <iostream>
对象的概念 对象是根据类的定义在程序中创建的一个抽象数据,用于解决某个子问题。这个抽象数据由 两部分组成:
对象的属性:记录和保存所解决子问题的状态 对象的方法/服务/成员函数:实现所解决子问题的状态的修改、展示
C++中类的语法 class class-name { private:
private-attribute-declaration-clauses private-method-declaration-clauses public: public-attribute-declaration-clauses public-method-declaration-clauses friend-class-declaration-clauses friend-function-declaration-clauses };
{ x = obj_.x+1;};
void CExampleA::funA() { CExampleA a; cout<<x<<" "<<a.x<<endl; return;
}
CExampleA funB(CExampleA arg) { CExampleA a; cout<<arg.x<<" "<<a.x<<endl; return arg;
};
void CExample::funA() { fun1(); fun2(); cout<<n<<endl; return;
}
void CExample::funB() { fun1(); fun2(); cout<<n<<endl; return;
注意:同类的两个对象之间可以进行赋值操作,对象赋值操作的实质是在两个内存块之间执 行按位复制操作
classA obj1, obj2; obj1=obj2;
obj1=obj2
obj1
obj2
obj1
obj2
小问题:阅读下面的程序,删除其中不符合语法的语句,然后给出该程序的输出结果。 #include <cstdlib> #include <iostream>
前对象的存储空间
如果在类 className 的定义中没有显式的声明构造函数 className (const className&
obj_),程序编译时编译器将自动添加一个构造函数 className (const className& obj_): 将 obj_所指向存储空间的数据按位复制到当
数的共同功能抽象成类的一个成员函数,这些新增的成员函数都作为类的 private 函 数 确定在程序中其他哪些类、函数需要访问该类的 private 属性,将这些类、函数声明 为类的 friend 对比:
int 是 C/C++语言提供的一种基本数据类型,用来创建存储整数的变量 结构体(struct)是在基本数据类型基础上定义的复合数据类型。
访问对象之前由系统自动执行
如果在类 className 的定义中没有显式的声明名为 className 的函数,程序编译时编 译器将自动添加 className 的两个构造函数 className (): 函数体为空 className (const className& obj_): 将 obj_所指向存储空间的数据按位复制到当
已有的其他类对象,创建一个当前类的对象
因此,每个类都有一个唯一的复制构造函数。
小问题:下面四个类,哪些类Fra bibliotek成员声明是不合法的?
class CExampleA {
class CExampleC {
int x;
int x;
public:
public:
void fun();
CExampleC(const CExampleC& obj_);
C++中对象的表示、创建、对象成员的访问 在程序中,可以用类定义变量、引用、指针来表示该类的一个对象 下列情形下,分别创建创类 classA 的一个对象 用 classA 声明一个变量,由系统根据所传递的参数确定被执行的构造函数 classA obj; 执行构造函数 classA::classA() classA obj(arg-list); 执行构造函数 classA::classA(arg-list) classA obj(arg-list), temp=obj; 执行构造函数 classA::classA(arg-list)创建对象 obj,执行复制构造函数 classA::classA(const classA&)创建对象 temp 执行 new 语句创建 classA 的一个对象,由系统根据所传递的参数确定被执行的 构造函数 函数访问时,classA 的一个对象作为某个参数值时,执行 classA 的复制构造函数 创建实参对象的一个复本 函数执行完毕,返回 classA 的一个对象的值时,执行 classA 的复制构造函数创建 一个返回值对象的一个复本 令对象 obj 所属类为 classA,函数 funB 中可以访问 obj: funB 是 obj 的成员函数、或者友元函数,则可访问 obj 的任何成员,包括其中的 private 成员 funB 是对象 obj_的成员函数,且 obj_所属类为 classA、obj_所属类为 classA 的友 元,则可访问 obj 的任何成员,包括其中的 private 成员程序的全局变量 除上述两种情况外,函数 funB 中只可访问 obj 的 public 成员
using namespace std;
class CExample { static int n; void fun1() {cout<<"hello "; return;}; static void fun2() {cout<<"n="; return;};
public: CExample() {n++;}; ~CExample() {n--;}; void funA(); static void funB();
using namespace std;
class CExampleB; class CExampleA {
int x; public:
CExampleA() { x = 0;}; CExampleA(int x_) { x = x_;}; CExampleA(const CExampleA& obj_) void funA(); friend class CExampleB; friend CExampleA funB(CExampleA arg); friend CExampleA funC(CExampleA& arg); };
void fun(); };
C++中类的析构函数 函数名为类名加前缀”~”,无返回值,无参数,由系统在接到释放对象占用的存储空 间申请之后、收回对象占用的存储空间之前自动执行 如果在类 className 的定义中没有显式的声明名析构函数,程序编译时编译器将自动 添加析构函数 ~className (): 函数体为空 当在类的构造函数中修改全局变量时,通常要定义析构函数:在释放对象时,恢复对 象创建时对全局变量的修改 类的静态成员为全局变量 例如:以一个全局变量记录当前游戏拼盘上的梯形积木总数 程序中每次创建一个梯形积木对象时,可通过构造函数在该全局变量上加1 程序中每次释放一个梯形积木对象时,可通过析构函数在该全局变量上减1 当对象的属性中记录了程序运行过程中所申请到的系统资源时,通常要定义析构函数: 在收回对象属性占用的存储空间前,释放这些系统资源 class CMyArray { int n; int* ptr; public: CMyArray(int n_) { n = n_; ptr = new int[n];}; CMyArray(const CMyArray& arg) { n = arg.n; ptr = new int[n];}; ~CMyArray() {delete[] ptr;}; ...... };
前对象的存储空间
一个类的定义中可以声明多个构造函数,但除上述两种情况外,程序编译时编译器不
会添加类的构造函数
对于类 className className (const className& obj_):被称为该类的复制构造函数,根据一个已有 的同类对象,创建一个新对象
className (const otherClassName& obj_):被称为该类的转换构造函数,根据一个
objA.funA(); temp.funA(); objB.fun(); objC.fun(); temp=funB(objA); temp.funA(); objA.funA(); temp=funC(objA); temp.funA(); objA.funA();
system("PAUSE"); return EXIT_SUCCESS; }
}
class CExampleC { int x;
public: void fun();
};
void CExampleC::fun() { CExampleA a; cout<<a.x<<endl; return;
}
int main(int argc, char *argv[]) { CExampleA objA(5), temp=objA; CExampleB objB; CExampleC objC;
};
void fun();
};
class CExampleB { int x;
public: CExampleB(); void fun(); };
class CExampleD { int x;
public: CExampleD(); CExampleD(const CExampleD& obj_);
C++中类的成员构成
两个或者更多个构造函数
其中一个构造函数称为复制构造函数,该构造函数的参数类型为当前类的常量型
引用
一个析构函数
任意数量的其他成员,包括属性和服务。可以对这些成员进行如下声明
static
const
&
C++中类的构造函数
与类同名,无返回值,可以有参数,在分配了对象需要的存储空间之后、应用程序可
类的抽象与封装部分的小结
类的概念 类是基于编程语言定义的一种抽象数据类型,描述程序中某个子问题的解决方案。这个抽象 数据类型具有两方面的作用:
描述采用什么样的数据结构记录和保存所解决子问题的状态:类的属性 描述采用什么样的算法实现所解决子问题的状态的修改、展示:类的方法/服务/成员
函数 设计一个类的工作包括:
}
CExampleA funC(CExampleA& arg){ CExampleA a;
cout<<arg.x<<" "<<a.x<<endl; return a; }
class CExampleB { int x;
public: void fun();
};
void CExampleB::fun() { CExampleA a; cout<<a.x<<endl; return;
确定解决这个子问题采用的数据结构和相应算法:类必须具有的属性、必须向程序其 他部分提供的 public 函数 如果属性所记录的数据需要直接向程序的其他部分展示,则将该属性作为 public 属性,否则作为类的 private 属性
这个子问题的起始状态必须满足的要求:类的构造函数 这个子问题在求解过程中需要占用哪些系统资源:类的析构函数 类成员函数的结构化:将其中复杂成员函数的功能划分到为多个函数、将多个成员函
小问题:请指出下列程序中不符合语法的语句。 #include <cstdlib> #include <iostream>
对象的概念 对象是根据类的定义在程序中创建的一个抽象数据,用于解决某个子问题。这个抽象数据由 两部分组成:
对象的属性:记录和保存所解决子问题的状态 对象的方法/服务/成员函数:实现所解决子问题的状态的修改、展示
C++中类的语法 class class-name { private:
private-attribute-declaration-clauses private-method-declaration-clauses public: public-attribute-declaration-clauses public-method-declaration-clauses friend-class-declaration-clauses friend-function-declaration-clauses };
{ x = obj_.x+1;};
void CExampleA::funA() { CExampleA a; cout<<x<<" "<<a.x<<endl; return;
}
CExampleA funB(CExampleA arg) { CExampleA a; cout<<arg.x<<" "<<a.x<<endl; return arg;
};
void CExample::funA() { fun1(); fun2(); cout<<n<<endl; return;
}
void CExample::funB() { fun1(); fun2(); cout<<n<<endl; return;
注意:同类的两个对象之间可以进行赋值操作,对象赋值操作的实质是在两个内存块之间执 行按位复制操作
classA obj1, obj2; obj1=obj2;
obj1=obj2
obj1
obj2
obj1
obj2
小问题:阅读下面的程序,删除其中不符合语法的语句,然后给出该程序的输出结果。 #include <cstdlib> #include <iostream>
前对象的存储空间
如果在类 className 的定义中没有显式的声明构造函数 className (const className&
obj_),程序编译时编译器将自动添加一个构造函数 className (const className& obj_): 将 obj_所指向存储空间的数据按位复制到当
数的共同功能抽象成类的一个成员函数,这些新增的成员函数都作为类的 private 函 数 确定在程序中其他哪些类、函数需要访问该类的 private 属性,将这些类、函数声明 为类的 friend 对比:
int 是 C/C++语言提供的一种基本数据类型,用来创建存储整数的变量 结构体(struct)是在基本数据类型基础上定义的复合数据类型。
访问对象之前由系统自动执行
如果在类 className 的定义中没有显式的声明名为 className 的函数,程序编译时编 译器将自动添加 className 的两个构造函数 className (): 函数体为空 className (const className& obj_): 将 obj_所指向存储空间的数据按位复制到当
已有的其他类对象,创建一个当前类的对象
因此,每个类都有一个唯一的复制构造函数。
小问题:下面四个类,哪些类Fra bibliotek成员声明是不合法的?
class CExampleA {
class CExampleC {
int x;
int x;
public:
public:
void fun();
CExampleC(const CExampleC& obj_);
C++中对象的表示、创建、对象成员的访问 在程序中,可以用类定义变量、引用、指针来表示该类的一个对象 下列情形下,分别创建创类 classA 的一个对象 用 classA 声明一个变量,由系统根据所传递的参数确定被执行的构造函数 classA obj; 执行构造函数 classA::classA() classA obj(arg-list); 执行构造函数 classA::classA(arg-list) classA obj(arg-list), temp=obj; 执行构造函数 classA::classA(arg-list)创建对象 obj,执行复制构造函数 classA::classA(const classA&)创建对象 temp 执行 new 语句创建 classA 的一个对象,由系统根据所传递的参数确定被执行的 构造函数 函数访问时,classA 的一个对象作为某个参数值时,执行 classA 的复制构造函数 创建实参对象的一个复本 函数执行完毕,返回 classA 的一个对象的值时,执行 classA 的复制构造函数创建 一个返回值对象的一个复本 令对象 obj 所属类为 classA,函数 funB 中可以访问 obj: funB 是 obj 的成员函数、或者友元函数,则可访问 obj 的任何成员,包括其中的 private 成员 funB 是对象 obj_的成员函数,且 obj_所属类为 classA、obj_所属类为 classA 的友 元,则可访问 obj 的任何成员,包括其中的 private 成员程序的全局变量 除上述两种情况外,函数 funB 中只可访问 obj 的 public 成员
using namespace std;
class CExample { static int n; void fun1() {cout<<"hello "; return;}; static void fun2() {cout<<"n="; return;};
public: CExample() {n++;}; ~CExample() {n--;}; void funA(); static void funB();
using namespace std;
class CExampleB; class CExampleA {
int x; public:
CExampleA() { x = 0;}; CExampleA(int x_) { x = x_;}; CExampleA(const CExampleA& obj_) void funA(); friend class CExampleB; friend CExampleA funB(CExampleA arg); friend CExampleA funC(CExampleA& arg); };
void fun(); };
C++中类的析构函数 函数名为类名加前缀”~”,无返回值,无参数,由系统在接到释放对象占用的存储空 间申请之后、收回对象占用的存储空间之前自动执行 如果在类 className 的定义中没有显式的声明名析构函数,程序编译时编译器将自动 添加析构函数 ~className (): 函数体为空 当在类的构造函数中修改全局变量时,通常要定义析构函数:在释放对象时,恢复对 象创建时对全局变量的修改 类的静态成员为全局变量 例如:以一个全局变量记录当前游戏拼盘上的梯形积木总数 程序中每次创建一个梯形积木对象时,可通过构造函数在该全局变量上加1 程序中每次释放一个梯形积木对象时,可通过析构函数在该全局变量上减1 当对象的属性中记录了程序运行过程中所申请到的系统资源时,通常要定义析构函数: 在收回对象属性占用的存储空间前,释放这些系统资源 class CMyArray { int n; int* ptr; public: CMyArray(int n_) { n = n_; ptr = new int[n];}; CMyArray(const CMyArray& arg) { n = arg.n; ptr = new int[n];}; ~CMyArray() {delete[] ptr;}; ...... };
前对象的存储空间
一个类的定义中可以声明多个构造函数,但除上述两种情况外,程序编译时编译器不
会添加类的构造函数
对于类 className className (const className& obj_):被称为该类的复制构造函数,根据一个已有 的同类对象,创建一个新对象
className (const otherClassName& obj_):被称为该类的转换构造函数,根据一个
objA.funA(); temp.funA(); objB.fun(); objC.fun(); temp=funB(objA); temp.funA(); objA.funA(); temp=funC(objA); temp.funA(); objA.funA();
system("PAUSE"); return EXIT_SUCCESS; }
}
class CExampleC { int x;
public: void fun();
};
void CExampleC::fun() { CExampleA a; cout<<a.x<<endl; return;
}
int main(int argc, char *argv[]) { CExampleA objA(5), temp=objA; CExampleB objB; CExampleC objC;
};
void fun();
};
class CExampleB { int x;
public: CExampleB(); void fun(); };
class CExampleD { int x;
public: CExampleD(); CExampleD(const CExampleD& obj_);
C++中类的成员构成
两个或者更多个构造函数
其中一个构造函数称为复制构造函数,该构造函数的参数类型为当前类的常量型
引用
一个析构函数
任意数量的其他成员,包括属性和服务。可以对这些成员进行如下声明
static
const
&
C++中类的构造函数
与类同名,无返回值,可以有参数,在分配了对象需要的存储空间之后、应用程序可
类的抽象与封装部分的小结
类的概念 类是基于编程语言定义的一种抽象数据类型,描述程序中某个子问题的解决方案。这个抽象 数据类型具有两方面的作用:
描述采用什么样的数据结构记录和保存所解决子问题的状态:类的属性 描述采用什么样的算法实现所解决子问题的状态的修改、展示:类的方法/服务/成员
函数 设计一个类的工作包括:
}
CExampleA funC(CExampleA& arg){ CExampleA a;
cout<<arg.x<<" "<<a.x<<endl; return a; }
class CExampleB { int x;
public: void fun();
};
void CExampleB::fun() { CExampleA a; cout<<a.x<<endl; return;
确定解决这个子问题采用的数据结构和相应算法:类必须具有的属性、必须向程序其 他部分提供的 public 函数 如果属性所记录的数据需要直接向程序的其他部分展示,则将该属性作为 public 属性,否则作为类的 private 属性
这个子问题的起始状态必须满足的要求:类的构造函数 这个子问题在求解过程中需要占用哪些系统资源:类的析构函数 类成员函数的结构化:将其中复杂成员函数的功能划分到为多个函数、将多个成员函