C++第14章 常量成员静态成员与友元

合集下载

C++ 类

C++ 类

4 读写函数与功能函数
功能函数不属于类的public接口,而是private成员函数, 支持类的public成员函数的操作。 读写函数用于读取或设置类的数据成员,它包括get函数 和set函数。get函数可以控制成员变量值的格式和显示。 set函数可以验证用户对成员变量的设置操作,从而确保 新值对成员变量是合适的。
2 构造函数
如果没有显式地为一个类提供一个拷贝构造函数,则 C++将会为该类提供一个默认的拷贝构造函数。默认拷 贝构造函数将逐个地完成类成员的拷贝,如果成员是 另一个类的对象,则将调用该类的拷贝构造函数或默 认拷贝构造函数。
3 析构函数
析构函数用于释放构造函数所分配资源,以供其他实例 使用。 类的析构函数名由类名称和逻辑非运算符(~)组成, 表示“逆构造函数”。 删除对象时会调用类的析构函数,即程序执行离开初始 化类对象的作用域时对类对象执行的自动操作。 构造函数不接收参数也不返回数值。类只能有一个析构 函数,而且析构函数不允许重载。每个类都有一个析构 函数。如果程序员没有显式提供析构函数,那么编译器 就会隐式地生成一个析构函数。
5 const类成员 类成员
使用关键字const声明的对象称为常量对象,而使用关键 字const声明的成员函数称为常量函数。 任何试图修改这种对象的操作都会产生语法错误。如果 将一个对象声明为常量对象,则该对象就不能调用类中 任何非常量型的成员函数(编译器隐式调用的构造函数 和析构函数出外)。 使用const声明的函数既不能修改对象的数据成员,也 不能调用同一类实例的非常量成员函数,否则,都将产 生编译错误。
6 友元
通过使用friend关键字来使一个函数或类成为另一个类 的友元函数或友元类。友元函数和友元类都有权访问类 的非public成员。 友元关系是人为指定的,而不是获取的。例如,如果要 让类B成为类A的友元,类A必须显式声明类B为自己的 友元。此外,友元关系既不对称也不能传递。例如,如 果类A是类B的友元,类B是类C的友元,并不能认为类 B是类A的友元(不对称),类C是类B的友元或类A是 类C的友元(不传递)。

c 关键字大全

c 关键字大全

C++关键字大全1. asm(汇编),用法如下:asm (指令字符串); 允许在C++程序中嵌入汇编代码。

2. auto(自动,automatic)是存储类型标识符,表明变量“自动”具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。

3. bool(布尔)类型,C++中的基本数据结构,其值可选为true(真)或者false(假)。

C++中的bool类型可以和int混用,具体来说就是0代表false,非0代表true。

bool类型常用于条件判断和函数返回值。

4. break(中断、跳出),用在switch语句或者循环语句中。

程序遇到break后,即跳过该程序段,继续后面的语句执行。

5. case用于switch语句中,用于判断不同的条件类型。

6. catch catch和try语句一起用于异常处理。

7. char char(字符,character)类型,C++中的基本数据结构,其值一般为0~255的int。

这256个字符对应着256个ASCII码。

char类型的数据需要用单引号’’括起来。

8. class class(类)是C++面向对象设计的基础。

使用class关键字声明一个类。

9. const const(常量的,constant)所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非const函数。

在函数的声明与定义时都要加上const,放在函数参数列表的最后一个括号后。

在C++中,用const声明一个变量,意味着该变量就是一个带类型的常量,可以代替#define,且比#define多一个类型信息,且它执行内链接,可放在头文件中声明;但在C中,其声明则必须放在源文件(即.C文件)中,在C中const声明一个变量,除了不能改变其值外,它仍是一具变量10. const_cast 用法:const_cast<type_id> (expression) 该运算符用来修改类型的const或volatile属性。

C++考试题库及答案

C++考试题库及答案

判断char型变量cl是否为小写字母的正确表达式是________。

(2.0分)A、(cl>='a')&&(cl<='z')B、('a'>=cl)||('z'<=cl)C、a'<=cl<='z'D、(cl>=a)&&(cl<=z)假定MyClass为一个类,则执行"MyClass a(2),b[5],*c[4]"后,执行构造函数的次数为________。

(2.0分)A、6B、11C、10D、5char *s1="hello",*s2;s2=s1;则________。

(2.0分)A、s1不能再指向其它单元B、cout<<s1;与cout<<s2;结果相同C、不能访问"hello"D、s2指向不确定的内存单元已知:p是一个指向类A数据成员m的指针,A1是类A的一个对象。

如果要给m赋值为5,正确的是________。

(2.0分)A、*A1.p=5;B、A1.*p=5;C、A1->p=5;D、A1.p=5;C++异常处理机制中没有________。

(2.0分)A、finallyB、tryC、throwD、catch所谓多态性是指________。

(2.0分)A、一个对象调用不同名称的对象B、一个对象调用不同名称的函数C、不同的对象调用相同名称的函数D、不同的对象调用不同名称的函数关于new运算符的下列描述中,________是错的。

(2.0分)A、使用它创建对象数组时必须指定初始值B、它可以用来动态创建对象和对象数组C、使用它创建对象时要调用构造函数D、使用它创建的对象和对象数组可以使用运算符delete删除以下正确的说法是:在C++语言中进行值传递时________。

C#中静态方法与非静态方法(static),公有与私有(public,private)

C#中静态方法与非静态方法(static),公有与私有(public,private)

C#中静态⽅法与⾮静态⽅法(static),公有与私有(public,private)梳理公有与私有,静态与⾮静态的应⽤1)公有与私有public(公有的):声明的⽅法和属性,可以被外部调⽤.private(私有的):声明的⽅法和属性,只能在本类中被调⽤,外部看不到.2)静态与⾮静态static(静态的):声明的⽅法和属性,不需要实例化就能被调⽤(公有/私有).C#静态⽅法与⾮静态⽅法⽐较⼀、C#静态成员:1、静态成员属于类所有,⾮静态成员属于类的实例所有。

2、每创建⼀个类的实例,都会在内存中为⾮静态成员新分配⼀块存储;⼆、C#静态⽅法1、C#静态⽅法属于类所有,类实例化前即可使⽤。

2、⾮静态⽅法可以访问类中的任何成员,静态⽅法只能访问类中的静态成员。

3、因为静态⽅法在类实例化前就可以使⽤,⽽类中的⾮静态变量必须在实例化之后才能分配内存,C#静态⽅法调⽤时⽆法判断⾮静态变量使⽤的内存地址。

所以⽆法使⽤。

⽽静态变量的地址对类来说是固定的,故可以使⽤。

三、C#静态⽅法是⼀种特殊的成员⽅法它不属于类的某⼀个具体的实例,⽽是属于类本⾝。

所以对静态⽅法不需要⾸先创建⼀个类的实例,⽽是采⽤类名.静态⽅法的格式。

1.static⽅法是类中的⼀个成员⽅法,属于整个类,即不⽤创建任何对象也可以直接调⽤!static内部只能出现static变量和其他static⽅法!⽽且static⽅法中还不能使⽤this…等关键字…因为它是属于整个类!2.静态⽅法效率上要⽐实例化⾼,静态⽅法的缺点是不⾃动进⾏销毁,⽽实例化的则可以做销毁。

3.静态⽅法和静态变量创建后始终使⽤同⼀块内存,⽽使⽤实例的⽅式会创建多个内存.4.C#中的⽅法有两种:实例⽅法,静态⽅法.静态⽅法销毁:主进程销毁时,内存中分配的静态⽅法销毁.四、获取类的名称C#静态⽅法中获取类的名称静态⽅法中⽤:string className = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName;⾮静态⽅法中还可以⽤:string className = this.GetType().FullName;。

C++类静态成员与类静态成员函数详解

C++类静态成员与类静态成员函数详解

C++类静态成员与类静态成员函数详解当将类的某个数据成员声明为static时,该静态数据成员只能被定义⼀次,⽽且要被同类的所有对象共享。

各个对象都拥有类中每⼀个普通数据成员的副本,但静态数据成员只有⼀个实例存在,与定义了多少类对象⽆关。

静态⽅法就是与该类相关的,是类的⼀种⾏为,⽽不是与该类的实例对象相关。

静态数据成员的⽤途之⼀是统计有多少个对象实际存在。

静态数据成员不能在类中初始化,实际上类定义只是在描述对象的蓝图,在其中指定初值是不允许的。

也不能在类的构造函数中初始化该成员,因为静态数据成员为类的各个对象共享,否则每次创建⼀个类的对象则静态数据成员都要被重新初始化。

静态成员不可在类体内进⾏赋值,因为它是被所有该类的对象所共享的。

你在⼀个对象⾥给它赋值,其他对象⾥的该成员也会发⽣变化。

为了避免混乱,所以不可在类体内进⾏赋值。

数据类型类名::静态数据成员名=初值不能⽤参数初始化表对静态成员初始化。

⼀般系统缺省初始为0。

静态成员是类所有的对象的共享的成员,⽽不是某个对象的成员。

它在对象中不占⽤存储空间,这个属性为整个类所共有,不属于任何⼀个具体对象。

所以静态成员不能在类的内部初始化,⽐如声明⼀个学⽣类,其中⼀个成员为学⽣总数,则这个变量就应当声明为静态变量,应该根据实际需求来设置成员变量。

复制代码代码如下:#include "iostream"using namespace std;class test{private:int x;int y;public:static int num;static int Getnum(){x+=5; // 这⾏代码是错误的,静态成员函数不能调⽤⾮静态数据成员,要通过类的对象来调⽤。

num+=15;return num;}};int test::num = 10;int main(void){test a;cout<<test::num<<endl; //10test::num = 20;cout<<test::num<<endl; //20cout<<test::Getnum()<<endl; //35cout<<a.Getnum()<<endl; //50system("pause");return 0;}通过上例可知: x+=5; // 这⾏代码是错误的静态函数成员必须通过对象名来访问⾮静态数据成员。

C++类中的静态成员变量和静态成员函数的作用

C++类中的静态成员变量和静态成员函数的作用

数据成员可以分静态变量、非静态变量两种.静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员.非成静态员:所有没有加Static的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问..非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中..一个类中也可以包含静态成员和非静态成员,类中也包括静态构造函数和非静态构造函数..分两个方面来总结,第一方面主要是相对于面向过程而言,即在这方面不涉及到类,第二方面相对于面向对象而言,主要说明static在类中的作用。

一、在面向过程设计中的static关键字1、静态全局变量定义:在全局变量前,加上关键字static 该变量就被定义成为了一个静态全局变量。

特点:A、该变量在全局数据区分配内存。

B、初始化:如果不显式初始化,那么将被隐式初始化为0(自动变量是随机的,除非显式地初始化)。

C、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。

例〔摘于C++程序设计教程---钱能主编P103〕://file1.cpp//Example 1#include <iostream.h>void fn();static int n; //定义静态全局变量void main(){n=20;cout < <n < <endl;fn();}void fn(){n++;cout < <n < <endl;}D、文件作用域下声明的const的常量默认为static存储类型。

静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。

对于一个完整的程序,在内存中的分布情况如以下图:代码区全局数据区堆区栈区一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。

C++友元函数和友元类(C++friend)详解

C++友元函数和友元类(C++friend)详解

C++友元函数和友元类(C++friend)详解私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接⼝(成员函数)间接地进⾏。

这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的⿇烦。

是从结构化的C语⾔发展⽽来的,需要照顾结构化设计程序员的习惯,所以在对私有成员可访问范围的问题上不可限制太死。

C++ 设计者认为,如果有的程序员真的⾮常怕⿇烦,就是想在类的成员函数外部直接访问对象的私有成员,那还是做⼀点妥协以满⾜他们的愿望为好,这也算是眼前利益和长远利益的折中。

因此,C++ 就有了友元(friend)的概念。

打个⽐⽅,这相当于是说:朋友是值得信任的,所以可以对他们公开⼀些⾃⼰的隐私。

友元分为两种:友元函数和友元类。

友元函数在定义⼀个类的时候,可以把⼀些函数(包括全局函数和其他类的成员函数)声明为“友元”,这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对象的私有成员了。

将全局函数声明为友元的写法如下:friend 返回值类型函数名(参数表);将其他类的成员函数声明为友元的写法如下:friend 返回值类型其他类的类名::成员函数名(参数表);但是,不能把其他类的私有成员函数声明为友元。

关于友元,看下⾯的程序⽰例。

1. #include<iostream>2. ug namespace std;3. class CCar; //提前声明CCar类,以便后⾯的CDriver类使⽤4. class CDriver5. {6. public:7. void ModifyCar(CCar* pCar); //改装汽车8. };9. class CCar10. {11. private:12. int price;13. friend int MostExpensiveCar(CCar cars[], int total); //声明友元14. friend void CDriver::ModifyCar(CCar* pCar); //声明友元15. };16. void CDriver::ModifyCar(CCar* pCar)17. {18. pCar->price += 1000; //汽车改装后价值增加19. }20. int MostExpensiveCar(CCar cars[], int total) //求最贵⽓车的价格21. {22. int tmpMax = -1;23. for (int i = 0; i<total; ++i)24. if (cars[i].price > tmpMax)25. tmpMax = cars[i].price;26. return tmpMax;27. }28. int main()29. {30. return 0;31. }这个程序只是为了展⽰友元的⽤法,所以 main 函数什么也不做。

常量函数知识点归纳总结

常量函数知识点归纳总结

常量函数知识点归纳总结常量函数是一种特殊的函数,它具有一些独特的特性和用途。

在编程中,了解常量函数的特点和用法对于设计和编写高质量的代码非常重要。

本文将对常量函数的定义、特点、用法以及相关注意事项进行归纳总结。

一、常量函数的定义常量函数是指在函数声明和定义中加上const关键字的函数。

在C++中,常量函数的声明和定义分别如下所示:```cpp// 声明常量函数void fun() const;// 定义常量函数void ClassName::fun() const {// 函数体}```在函数声明和定义的参数列表后加上const关键字即可将函数声明为常量函数。

这使得函数在被调用时无法修改成员变量的值,从而实现了常量函数的特性。

二、常量函数的特点常量函数具有以下几个特点:1. 不能修改成员变量:在常量函数中,不允许修改任何类的成员变量。

即使类的成员变量被声明为可变的(mutable),常量函数也不能修改它们的值。

2. 只能调用其他常量函数:常量函数只能调用其他常量函数,因为非常量函数有可能修改成员变量的值,这与常量函数的特性相悖。

3. 适用于常量对象:常量函数通常用于处理常量对象,因为常量对象的成员变量不能被修改。

通过使用常量函数,可以确保对常量对象的操作不会改变对象的状态。

4. 不产生副作用:由于常量函数不能修改成员变量的值,它不会产生副作用。

这使得常量函数更加安全和可靠,有利于编写健壮的代码。

5. 表现为类的不变性:常量函数可以用来表现类的不变性(invariant),即类在某一时间段内不会发生变化的特性。

通过在常量函数中实现不变性,可以确保对象的状态不会被错误地修改。

三、常量函数的用法常量函数在实际编程中具有多种用途,主要包括以下几个方面:1. 处理常量对象:常量函数通常用于处理常量对象,以确保对象的状态不会被修改。

这对于编写高质量的代码非常重要,可以避免在对象被错误地修改时引发不确定的行为。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

重 载 函 数
14.2 常量成员函数
class Circle{ public: Circle(double r); // 构造函数 double area() const ; // 常量成员函数 double perimeter() const ; // 常量成员函数 double getRadius() const ; // 常量成员函数 private: double radius; const double PI; // 常量数据成员 }; Circle::Circle(double r): radius(r), PI(3.1415) { } double Circle::area() const { return PI*radius*radius; 建议:将不修改类数据成员值的 } double Circle::perimeter() const { 成员函数定义为常量成员函数。 return 2*PI*radius; } double Circle::getRadius() const { return radius; 注意:在类外实现常量成员函数时也要带const }
常量是一个在程序执行过程中其值不能改变的量。C++通过关 键字 const 来定义一个常量。常量在定义时必须进行初始化! 例: const double PI = 3.1415; const double DC; PI = 3.1415926; // 常量定义并初始化 // 错误!必须进行初始化! // 错误!不允许修改!
14.4 静态数据成员
类是类型而不是具体的数据对象,类的对象都是该类的实 例,每个类对象都具有自己的数据成员,而且是相互独立,各 自占内存空间。 然而,程序中往往需要让类的所有对象在类的范围内共享 某个数据。 Student private: int count; // 班级人数
通过静态数据成员来实现
{ //… }
类外: 类型标识符 类名::成员函数名(参数列表) const // 实现
{ //… }
14.2 常量成员函数 说明:
• const 是函数类型的一个组成部分,因此在实现部分也要带 const 关键字。 • 常量成员函数不更新对象的数据成员,也不能调用该类中没 有用 const 修饰的成员函数。 • const 关键字可以参与区分重载函数。
14.2 常量成员函数
class Circle{ public: Circle(double r): radius(r), PI(3.1415) // 初始化表 {} double area() const { // 常量成员函数 return PI*radius*radius; } double perimeter() const { // 常量成员函数 return 2*PI*radius; } double getRadius() { // 普通成员函数 return radius; } double getRadius() const { // 重载常量成员函数 return radius; } private: double radius; const double PI; // 常量数据成员 };
注意:常对象只能调用它的常量成员函数,而不能调 用其他成员函数。
14.3 常对象
#include <iostream> using namespace std; class Rectangle{ public: Rectangle(): width(0.0), height(0.0) { } // 默认构造函数 Rectangle(double w, double h): width(w), height(h) { } // 带参数的构造函数 double area() const { // 常量成员函数 return width*height; } double perimeter() const { // 常量成员函数 return 2*(width+height); } void print(){ // 普通成员函数 cout<<“Width: ”<<width<<“, Height: ”<<height<<endl; } void print() const { // 重载常量成员函数 cout<<“Width: ”<<width<<“, Height: ”<<height<<endl; } private: double width; double height; };
14.4 静态数据成员 静态数据成员:
• 静态数据成员通过 static 关键字进行定义。 • 所有对象的静态数据成员占用同一个内存空间(只有一份)。 • 静态数据成员可以实现数据共享。 • 静态数据成员属于一个类而不属于该类的任何对ቤተ መጻሕፍቲ ባይዱ。 • 静态数据成员可以独立于对象存在和被引用。
14.4 静态数据成员 静态数据成员定义:
14.1 常量数据成员
#include <iostream> #include <cstring> using namespace std; class Student{ public: Student(char *_name, int _id, bool _sex): id(_id), sex(_sex){ name = new char[strlen(_name)+1]; strcpy(name, _name); 常量数据成员: } const 类型 标识符; ~Student() { if(name!=NULL) 类型 const 标识符; delete [ ] name; } int main(){ const char * getName() { return name; } Student p(“John”, 11151, true); int getID() { return id; } cout<<“姓名: ”<<p.getName()<<endl; bool getSex() { return sex; } cout<<“学号: ”<<p.getID()<<endl; protected: cout<<“性别: ”<<p.getSex()<<endl; char *name; // 姓名 return 0; int const id; // 学号 } bool const sex; // 性别 };
static 类型标识符 静态数据成员名; // 类内
静态数据成员初始化:
类型标识符 类名::静态数据成员名 = 初始值; // 类外
说明:
• 静态数据成员的初始化放在类体外进行(必须初始化)。 • 初始化时前面不允许再加 static 关键字。 • 初始化时使用作用域运算符来标明它所属的类。 • 访问静态数据成员: 类名::静态数据成员名
14.3 常对象 常对象(const 对象):
常对象的所有数据成员在程序执行过程中都不能被修改。
定义形式:
const 类名 对象名; 或 const 类名 对象名(参数列表);
类名 const 对象名; 或 类名 const 对象名(参数列表);
例: const Circle cp(13.14); Circle const cp(13.14); // 常对象定义 // 常对象定义
14.2 常量成员函数 常量成员函数(const 成员函数):
• 常量成员函数只能引用类中的数据成员而不能修改它们的值。
• 只有常量成员函数才有资格操作常对象。
定义形式: 类内: 类型标识符 成员函数名(参数列表) const; 类型标识符 成员函数名(参数列表) const // 声明 // 定义
14.3 常对象
int main() { Rectangle rect1(2.0, 3.0); // 普通对象 cout<<“Area: ”<<rect1.area()<<endl; // 调用常量成员函数 rect1.print(); // 调用普通成员函数
const Rectangle rect2(4.0, 5.0); // 常对象 cout<<“Area: ”<<rect2.area()<<endl; // 调用常量成员函数 rect2.print(); // 调用常量成员函数
return 0; }
常对象只能调用常量成员函数,而普通对象既可以调用 普通成员函数,也可以调用常量成员函数。但当发生 const重载时,普通对象调用是非const成员函数,而常 对象调用的是带const的成员函数。
Ch14_01
14.3 常对象
#include <iostream> using namespace std; class Complex{ public: Complex(double r = 0.0, double img = 0.0): real(r), image(img) { } void set(double r, double img) { real = r; image = img; } double getReal() const { return real; } double getImage() const { return image; } void print() const { cout<<real<<“+”<<image<<“i”<<endl; } private: double real; double image; }; void add(const Complex &cp1, const Complex &cp2){ Complex result; result.set(cp1.getReal()+cp2.getReal(), cp1.getImage()+cp2.getImage()); result.print(); } int main(){ const引用对象和const指针对 Complex cp1(1.0, 2.0), cp2(3.0, 4.0); 象只能访问类的常量成员函数。 add(cp1, cp2); return 0; }
相关文档
最新文档