-
类和对象
2019-01-03 14:30:32对象是指类的实例,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的应用性、灵活性和扩展性。C++是基于面向对象的语言。 特点 封装、继承、多态 三种访问限定符 public(公有) protected...面向对象程序设计
- 概念
面向对象程序设计是一种程序设计范型,同时也是一种程序开发的方法。对象是指类的实例,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的应用性、灵活性和扩展性。C++是基于面向对象的语言。 - 特点
封装、继承、多态 - 三种访问限定符
public(公有)
protected(保护)
private(私有)
注:
- public成员可以从类外部直接访问,prevate、protected成员不能从类外直接访问。
- 类体中如果没有定义限定符,则默认为私有的。
- 作用域
作用域分为局部域、全局域、类域以及名字空间域。
其中类的作用域:
- 每个类都定义了自己的作用域,类的成员(成员函数/成员变量)都在这个作用域内,成员函数内可任意访问成员变量和其他成员函数。
- 对象可以通过直接访问公有成员,指向对象的指针通过->也可以直接访问对象的公有成员。
- 在类体外定义成员,需要使用 :: 作用域解析符指明成员属于哪个类域。
类和对象
-
类是现实世界或思维世界在实体计算机中的反映,它将数据以及这些数据上的操作封装在一起。对象是具有类型的变量。对象是类的实例,类是对象的模板。
-
成员函数的声明和定义
1.类内定义成员函数
class Date { public: void Display() { cout << _year << "-" << _month << "-" << _day << endl; } public : int _year; //年 int _month; //月 int _day; //日 };
2.类外定义成员函数
class Date { public: void Display(); public : int _year; //年 int _month; //月 int _day; //日 }; void Date :: Display() { cout << _year << "-" << _month << "-" << _day << endl; }
- 类实例化对象
- 类限定了类内有哪些成员,定义了一个类并没有分配实际的内存空间来存储它。
- 一个类可以实例化出多个对象,实例化出的对象占有实际的物理空间存储类成员变量。
- 类并没有实际存储数据,实例化出的对象才能实际存储数据,占用物理空间。
例:
class Date { public: void Display() { cout << _year << "-" << _month << "-" << _day << endl; } public : int _year; //年 int _month; //月 int _day; //日 }; void Test() { Date day; //实例化对象 day._year = 1900; day._month = 1; day._day = 1; day.Display(); }
- 类对象存储模型
每个对象的大小为类中所有成员变量的大小之和,遵循内存对齐原则。
//结构体内存对齐规则:
- 第一个成员在结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 (对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值)
- 结构体总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数)的整数倍。
- 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(函嵌套结构体的对齐数)的整数倍。
- 隐含的this指针
- 每个成员函数都有一个指针形参,它的名字是固定的,称为this指针,this指针是隐式的。(构造函数比较特殊,没有这个隐含的this指针)
- 编译器会对成员函数进行处理,在对象调用成员函数时,对象地址作实参传递给成员函数的第一个形参this指针。
- this指针是成员函数隐含指针形参,是编译器自己处理的,我们不能在成员函数的形参中添加this指针的参数定义,也不能在显示传递对象的地址给this指针。
类的默认成员函数
1 . 构造函数
-
成员变量是私有的,要对他们进行初始化,必须用一个公有成员函数来进行。同时这个函数应该有且仅在定义对象时自动执行一次,这时调用的函数称为构造函数。
-
构造函数是特殊的成员函数,其函数名与类名相同,无返回值,在对象构造(实例化)时系统自动调用对应的构造函数;其构造函数可以重载,且可以在类中定义,也可以在类外定义;如果定义中没有给出构造函数,则C++编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数。无参的构造函数和全缺省的构造函数都认为是缺省构造函数,并且缺省的构造函数只能有一个。
-
以日期类为例,其(有全缺省参数的)构造函数如下:
#include<iostream> using namespace std; class Date { public: //此处为带参数的构造函数,函数名与类名相同,无返回值 Date(int year = 1900,int month = 1, int day = 1) { _year = year; _month = month; _day = day; } void Display() { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; } int main() { Date d1(2018,4,25); d1.Display(); Date d2; d2.Display(); return 0; }
结果为:
2 . 拷贝构造函数
- 创建对象时使用同类对象来进行初始化,这时使用的函数是拷贝构造函数(一种特殊的构造函数)。
- 拷贝构造函数其实是一个构造函数的重载。其参数必须使用引用传参,使用传值方式会引发无穷递归调用。若未显示定义,系统会默认缺省的拷贝构造函数,缺省的拷贝构造函数会,依次拷贝类成员进行初始化。
例:
#include<iostream> using namespace std; class Date { public: //构造函数 Date(int year = 1900,int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //拷贝构造函数 Date(const Date& d) { _year = d._year; _month = d._month; _day = d._day; } void Display() { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; } int main() { Date d1(2018,1,1); d1.Display(); Date d2; d2.Display(); Date d3(d1); d3.Display(); return 0; }
结果为:
3 . 析构函数
- 当一个对象的生命周期结束时,C++编译器会自动调用一个成员函数,这个特殊的成员函数即析构函数。
- 析构函数在类名上加~,无参数无返回值。一个类有且只有一个析构函数,若未定义,系统会自动生成缺省的析构函数。析构函数体内并不是删除对象,而是做一些清理工作。
4 . 赋值操作符重载
- 为了增强程序可读性,C++支持运算符的重载。重载运算符以后,不能改变运算符的优先级/结合性/操作个数等。
- 对一个已存在的对象进行拷贝赋值。
class Date { public: //构造函数 Date(int year = 1900,int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //赋值操作符的重载 d2 = d1 Date operator=(const Date& d) //传引用 { if (this != &d) //避免自己给自己赋值 { return _year = d._year; _month = d._month; _day = d._day; } return *this; } void Display() { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; } int main() { Date d1(2018,1,1); d1.Display(); Date d2; d2 = d1; d2.Display(); return 0; }
结果为:
- 编译器的处理过程:
- 赋值运算符的重载和拷贝构造的区别
5 . 取地址操作符重载及const修饰的取地址操作符重载
(这两个默认成原函数一般不用重新定义)const & 内联 &静态成员 & 友元
1.const成员函数
- 在成员函数后面加const,const修饰this指针所指向的对象,也就是保证调用这个const成员函数的对象在函数内不会被改变。
- 若成员函数需要修改成员变量,则不用const;若成员函数不需要修改成员变量,则尽量使用用const。
- const成员函数内不能调用非const成员,非const成员函数内可以调用const成员。
class Date { public: void Display() { cout << _year << "-" << _month << "-" << _day << endl; } void Display() const { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; } int main() { Date d1; d1.Display(); const Date d2; d2.Display(); return 0; }
- 编译器对const成员函数的处理
2.inline(内联)-
以inline修饰的函数叫做内联函数,编译时C++编译器会调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。
-
inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的的函数不适宜使用内联。
-
inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉.
内联。 -
inline必须函数定义放在一起,才能成为内联函数,仅将inline放在声明前是不起不作用的。
-
定义在类内的成员函数默认定义为内联函数。
3.类的静态成员- 类里面static修饰的成员,称为静态类成员 。
- 类的静态成员是该类的所有成员对象所共享的。
class Date { public: Date() { cout << "Date ()" << endl; ++sCount; } void Display() { cout << "year:" << _year << endl; cout << "month:" << _month << endl; cout << "day:" << _day << endl; } //静态成员函数 static void PrintCount() { cout << "Date Count:" << sCount << endl; } private: int _year; int _month; int _day; static int sCount; //静态成员变量,统计创建时间个数 }; //定义并初始化静态成员变量 int Date::sCount = 0; void Test() { Date d1, d2; //访问静态成员 Date::PrintCount(); }
注:静态成员函数没有隐含的this指针,所以可以使用类型::作用域访问符直接访问静态成员函数。
- 友元
- 友元函数
在C++中友元函数允许在类外访问该类中的任何成员,就像成员函数一样;友元函数用关键字friend修饰。
1) 友元函数不是类的成员函数。
2) 友元函数可以通过对象访问所有成员,私有和保护成员也一样。
class Date { //友元函数 friend void Display(const Date &d); private: int _year; int _month; int _day; }; void Display(const Date& d) { cout << "year:" << d._year << endl; cout << "month:" << d._month << endl; cout << "day:" << d._day << endl; } void Test() { Date d1; Display(d1); }
- 友元类
整个类可以是另一个类的友元类。友元类中每个成员函数都是另一个类的友元函数,都可以访问另一个类中的保护或私有数据成员。
class Time { //Date 是 Time的友元,所以Date可以访问Time的所有成员 friend class Date; private: int _hour; int _minute; int _second; }; class Date { public: void Display() { cout << "year:" << _year << endl; cout << "month:" << _month << endl; cout << "day:" << _day << endl; //定义为友元类后,可以访问Time类对象的所有成员 cout << "hour:" << _t._hour << endl; cout << "minute:" << _t._minute << endl; cout << "second:" << _t._second << endl; } private: int _year; int _month; int _day; Time _t; }; void Test() { Date d1; d1.Display(); }
- 概念
-
类和对象(一)——类&对象概念及定义
2018-05-22 00:09:19面向对象程序设计(OOP)是一种程序设计的泛型,同时也是一种程序开发的方法,它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性二、类和对象的概念1. 类:类是现实世界在...c++是基于面向对象的语言,并不是纯面向对象的语言,因为它包含c的部分,c是面向过程的语言
一、面向对象
概念:面向对象程序设计(OOP)是一种程序设计的泛型,同时也是一种程序开发的方法,它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性
二、类和对象的概念
1. 类:类是现实世界在计算机中的反映,它将数据和对这些数据的操作封装在一起(并没有开空间)
2. 对象:类的实例(占有实际的空间)
class Student //类 { public: Student() {} private: int _num; char* _name; int _age; }; int main() { Student s; //对象-> 类的实例 system("pause"); return 0; }
1)类相当于盖楼房的图纸一样,虽然定义了有哪些成员,但并没有实际的空间
2)类可以实例化出多个对象,实例化出的对象占有实际空间(用来存储成员变量)
三、类的三大特性:
1.封装 2.继承 3.多态
封装:函数的封装是一种形式,隐藏对象的属性和实现细节(函数内部),仅仅对外提高函数的接口和对象进行交互。
类的访问限定符可以协助其完成封装
四、类的三个访问限定符
1.public:公有的,类的成员可以从类外直接访问
2.private/protected:类的成员不能从类外直接访问
3.类的每个访问限定符可以多次在类中使用,作用域为从该限定符开始到下一个限定符之前/类结束
4.类中如果没有定义限定符,则默认为私有的(private)
5.类的访问限定符体现了类的封装性
因为_name是私有的,所以在类外不能使用,而_age,Eat()是公有的,所以在类外可以直接使用
五、类的定义
1.定义一个简单的类
2.类的对象可以直接通过 . 来访问类的公有成员,类的对象指针可以通过->来访问类的公有成员
class person { public: void Display() { cout << _name <<"-"<< _age << endl; } public: int _age; char* _name; }; int main() { person p; p._age = 18; p._name = "peter"; p.Display(); person* ptr = &p; ptr->_age = 20; ptr->_name = "jack"; ptr->Display(); system("pause"); return 0; }
3.类外定义成员函数,需要使用::(作用域解析符)指明其属于哪个类
class person { public: void Display(); //声明 }; void person::Display()//类外定义 { //...... }
六、类的大小
类的成员函数放在公共代码区,所有该类的对象共享这些成员函数,每个对象的大小为类内成员变量的大小之和,遵循内存对齐原则
1.为什么要内存对齐?
答:为了提高程序的性能,方便cpu访问内存,处理器并不是一个字节一个字节来访问内存,一般是4个字节或8个字节
2.空类占多少个字节?为什么?
答:空类占1个字节,占位用,告诉系统我这里定义了一个类,虽然它是空的
-
Java类和对象 详解(一)
2016-10-06 20:48:02一、面向对象简述面向对象是一种现在最为流行的程序设计方法,几乎现在的所有应用都以面向对象为主了,最早的面向对象的概念实际上是由IBM提出的,在70年代的Smaltalk语言之中进行了应用,后来根据面向对象的设计...一、面向对象简述
面向对象是一种现在最为流行的程序设计方法,几乎现在的所有应用都以面向对象为主了,最早的面向对象的概念实际上是由IBM提出的,在70年代的Smaltalk语言之中进行了应用,后来根据面向对象的设计思路,才形成C++,而由C++产生了Java这门面向对象的编程语言。
但是在面向对象设计之前,广泛采用的是面向过程,面向过程只是针对于自己来解决问题。面向过程的操作是以程序的基本功能实现为主,实现之后就完成了,也不考虑修改的可能性,面向对象,更多的是要进行子模块化的设计,每一个模块都需要单独存在,并且可以被重复利用,所以,面向对象的开发更像是一个具备标准的开发模式。
在面向对象定义之中,也规定了一些基本的特征:
(1)封装:保护内部的操作不被破坏;
(2)继承:在原本的基础之上继续进行扩充;
(3)多态:在一个指定的范围之内进行概念的转换。对于面向对象的开发来讲也分为三个过程:OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)。
二、类与对象的基本概念
类与对象时整个面向对象中最基础的组成单元。
类:是抽象的概念集合,表示的是一个共性的产物,类之中定义的是属性和行为(方法);
对象:对象是一种个性的表示,表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性来区分不同对象。可以一句话来总结出类和对象的区别:类是对象的模板,对象是类的实例。类只有通过对象才可以使用,而在开发之中应该先产生类,之后再产生对象。类不能直接使用,对象是可以直接使用的。
三、类与对象的定义和使用
在Java中定义类,使用关键字class完成。语法如下:
class 类名称 { 属性 (变量) ; 行为 (方法) ; }
范例:定义一个Person类
class Person { // 类名称首字母大写 String name ; int age ; public void tell() { // 没有static System.out.println("姓名:" + name + ",年龄:" + age) ; } }
类定义完成之后,肯定无法直接使用。如果要使用,必须依靠对象,那么由于类属于引用数据类型,所以对象的产生格式(两种格式)如下:
(1)格式一:声明并实例化对象
类名称 对象名称 = new 类名称 () ;
(2)格式二:先声明对象,然后实例化对象:
类名称 对象名称 = null ; 对象名称 = new 类名称 () ;
引用数据类型与基本数据类型最大的不同在于:引用数据类型需要内存的分配和使用。所以,关键字new的主要功能就是分配内存空间,也就是说,只要使用引用数据类型,就要使用关键字new来分配内存空间。
当一个实例化对象产生之后,可以按照如下的方式进行类的操作:
对象.属性:表示调用类之中的属性;
对象.方法():表示调用类之中的方法。范例:使用对象操作类
package com.wz.classandobj; class Person { String name ; int age ; public void get() { System.out.println("姓名:" + name + ",年龄:" + age); } } public class TestDemo { public static void main(String args[]) { Person per = new Person() ;// 声明并实例化对象 per.name = "张三" ;//操作属性内容 per.age = 30 ;//操作属性内容 per.get() ;//调用类中的get()方法 } }
运行结果:
姓名:张三,年龄:30
以上完成了一个类和对象的操作关系,下面换另外一个操作来观察一下:
package com.wz.classandobj; class Person { String name ; int age ; public void get() { System.out.println("姓名:" + name + ",年龄:" + age); } } public class TestDemo { public static void main(String args[]) { Person per = null;//声明对象 per = new Person() ;//实例化对象 per.name = "张三" ;//操作属性内容 per.age = 30 ;//操作属性内容 per.get() ;//调用类中的get()方法 } }
运行结果:
姓名:张三,年龄:30
那么,问题来了,以上两种不同的实例化方式有什么区别呢?
我们从内存的角度分析。首先,给出两种内存空间的概念:
(1)堆内存:保存对象的属性内容。堆内存需要用new关键字来分配空间;
(2)栈内存:保存的是堆内存的地址(在这里为了分析方便,可以简单理解为栈内存保存的是对象的名字)。任何情况下,只要看见关键字new,都表示要分配新的堆内存空间,一旦堆内存空间分配了,里面就会有类中定义的属性,并且属性内容都是其对应数据类型的默认值。
于是,上面两种对象实例化对象方式内存表示如下:
两种方式的区别在于①②,第一种声明并实例化的方式实际就是①②组合在一起,而第二种先声明然后实例化是把①和②分步骤来。
另外,如果使用了没有实例化的对象,结果如何?
如下:package com.wz.classandobj; class Person { String name ; int age ; public void get() { System.out.println("姓名:" + name + ",年龄:" + age); } } public class TestDemo { public static void main(String args[]) { Person per = null;//声明对象 //per = new Person() ;//实例化对象 per.name = "张三" ;//操作属性内容 per.age = 30 ;//操作属性内容 per.get() ;//调用类中的get()方法 } }
运行结果:
Exception in thread "main" java.lang.NullPointerException at com.wz.classandobj.TestDemo.main(TestDemo.java:15)
此时,程序只声明了Person对象,但并没有实例化Person对象(只有了栈内存,并没有对应的堆内存空间),则程序在编译的时候不会出现任何的错误,但是在执行的时候出现了上面的错误信息。这个错误信息表示的是“NullPointerException(空指向异常)”,这种异常只要是应用数据类型都有可能出现。
四、对象引用传递初步分析
引用传递的精髓:同一块堆内存空间,可以同时被多个栈内存所指向,不同的栈可以修改同一块堆内存的内容。
下面通过若干个程序,以及程序的内存分配图,来进行代码的讲解。
我们来看一个范例:
class Person { String name ; int age ; public void tell() { System.out.println("姓名:" + name + ",年龄:" + age) ; } } public class TestDemo { public static void main(String args[]) { Person per1 = new Person() ; // 声明并实例化对象 per1.name = "张三" ; per1.age = 20 ; Person per2 = per1 ; // 引用传递 per2.name = "李四" ; per1.tell() ; } }
对应的内存分配图如下:
再来看另外一个:
class Person { String name ; int age ; public void tell() { System.out.println("姓名:" + name + ",年龄:" + age) ; } } public class TestDemo { public static void main(String args[]) { Person per1 = new Person() ; // 声明并实例化对象 Person per2 = new Person() ; per1.name = "张三" ; per1.age = 20 ; per2.name = "李四" ; per2.age = 30 ; per2 = per1 ;// 引用传递 per2.name = "王五" ; per1.tell() ; } }
对应的内存分配图如下:
垃圾:指的是在程序开发之中没有任何对象所指向的一块堆内存空间,这块空间就成为垃圾,所有的垃圾将等待GC(垃圾收集器)不定期的进行回收与空间的释放。
未完待续。。。
-
C++类和对象数组
2018-05-14 23:47:15C++类和对象数组 【1】对象数组 1:对象数组的定义:类名 数组名[元素个数] Eg: student asa[10];//有10个元素的学生类对象数组 2:对象数组的访问形式:数组名[下标].成员名; Eg: asa[j].print(); 3:对象...C++类和对象数组
【1】对象数组
1:对象数组的定义:类名 数组名[元素个数]
Eg: student asa[10];//有10个元素的学生类对象数组
2:对象数组的访问形式:数组名[下标].成员名;
Eg: asa[j].print();
3:对象数组的初始化:对象数组的初始化通常也是由构造函数来完成的。
Eg: #include”student.h”
int main
{
student asa[4]={student(1,“LiMing”,98),student(2,”Bill”,89),student(3,”Chlily”,99),student(4,”Saraea”,96)};
for(int i=0;i<4;i++)
asa[i].print();
return 0;
}
【2】指向对象的指针
1:对象指针的用法:定义对象指针的语法和定义其它基本数据类型指针的语法相同。在使用对象指针之前,要把它指向一个已经创建的对象,然后才能访问该对象的成员。在使用对象名来访问对象成员时,要使用点运算符“.”。如果要通过指向对象的指针来访问对象的成员,那么必须使用箭头运算符“->”。
【3】this指针
Eg: class student
{
int number;
char name[15];
float score;
void display()
{
cout<<”number: ”<<number;
cout<<”name: ”<<name;
cout<<”score: ”<<score;<<endl;
}
};
1:在成员函数display()中有一个隐藏的指针作为参数,该指针参数使用关键字this命名,它是指向该类对象的指针,成员函数可以通过它来访问该类对象的数据成员。voiddisplay(student *this)//this指针由编译器自动生成。
2:this指针是由C++编译器自动产生的一个隐含指针,编译器将该指针自动插入到类的所有成员函数的参数列表中,成员函数使用该指针来存取对象的数据成员。
3:内存中只有一份成员函数的备份,而且对象的实例变量和成员函数是分开存放的,eg:X const *this。当对象调用该函数时,编译器自动将该对象的地址作为实参传递给相应的成员函数的this指针。
Eg:void date::set(date* constthis,int d,int m,int y)
{
this->day=d;
this->month=m;
this->year=y;
}
注意:this指针由编译器自动生成,程序员不能将this指针的说明写在函数中,否则将出现编译时间错误信息。
4:this指针是系统的一个内部指针,通常以隐式方式使用,但也可以被程序员显式使用,例如,当运算符重载和建立双向链表时,显式使用this指针十分必要。
【4】对象的赋值:如果两个对象属于同一种类类型,换句话说,两个对象是由同一个类声明的,那么我们可以将其中的一个对象的值(属性值)赋给另一个对象。默认情况下,当将一个对象赋值给另一个对象时,第一个对象的数据将被按位复制到第二个对象中。对象的赋值仅仅是使两个对象的值相等,而这两个对象仍然是相互独立的,即修改一个对象的值将不会影响到另一个对象。
Eg:Rectangle rect1(10,20),rect2(0,0);
rect2=rect1;
【5】对象作为函数参数:分类:传值调用,传址调用
1:传值调用:传值调用,传送的是作为实际参数的对象的拷贝而不是实际对象的本身。因此在函数中改变对象的值不会影响作为实际参数对象本身。
Class Square
{
int side;
public:
void set(int x) {side=x;}
void out() {cout<<side<<”\n”;}
};
void f(square x)
{
x.out();
x.set(100);
x.out();
}
int main()
{
Square s;
s.set(10);
f(s);
s.out();
return 0;
}
2:传址调用:当函数调用时传递的是作为实际参数的对象的地址,就是传址调用方式。在函数中对作为形式参数的对象的修改实际上就是对作为实际参数的对象的修改。我们既可以使用对象的引用来实现传址调用,也可以用指针来实现。
使用对象的引用来实现传址调用:
Class Square
{
int side;
public:
void set(int x){side=x;}
void out() {cout<<side<<”\n”;}
};
void f(square &x)//对象的引用作为函数的参数
{
x.out();
x.set(100);
x.out();
}
int main()
{
Square s;
s.set(10);
f(s);
s.out();
return 0;
}
使用指向对象的指针来实现传址调用的例子
Class Square
{
int side;
public:
void set(int x){side=x;}
void out() {cout<<side<<”\n”;}
};
void f(square *x)
{
x.out();
x.set(100);
x.out();
}
int main()
{
Square s;
s.set(10);
f(&s);
s.out();
return 0;
}
【6】从函数返回对象:当函数返回对象时,函数创建了一个临时对象来保存要返回的值,而函数所返回的对象实际上是这个临时对象。在对象的值被返回之后,临时对象将被销毁。
Eg:mystring input()
{
char instr[80];
mystring str;
cin>>instr;
str.set(instr);
return str;//返回一个mystring对象
}
int main()
{
Mystring ob;
ob=.input();
ob.print();
return 0;
}
【7】类的静态成员
1:静态成员:C中通过在变量定义的前面加static关键字就可以将变量声明为静态变量。采用局部静态变量可以减少全局变量的使用:将全局变量声明为静态的可以降低全局变量的副作用。C++中通过在类的成员函数前面加上static关键字将其成员声明为静态成员,一个类的静态成员既可以是静态数据成员,也可以是静态成员函数。
-
静态数据成员
声明类的静态数据成员的方式是在变量定义的前面加static关键字
classstudent
{
private:
int num;
char *name;
float score;
static int count;
static float sum;//类student的静态数据成员的声明
public:
……
};
intstudent::count=0;
floatstudent::sum=0; //静态成员变量应在创建类的对象前定义并进行初始化
一个类的静态数据成员为该类的所有对象所共有,不管创造了这个类的多少个对象,其静态数据成员在内存中只有一份拷贝。由于只有一个类的静态成员只有一份拷贝,所以我们经常使用“类名::”来访问静态数据成员。例如:counter::count=0;
静态成员变量的最一般的作用就是对一些共享资源提供存取控制。
静态成员好处就是减少了全局变量的使用。
静态成员主要作用就是定义类的各个对象所共用的数据,如统计总数,平均数等。
2:静态成员函数:在类的成员函数前面加上static关键字说明的函数就是静态成员函数。只使用静态数据成员的函数可以定义为静态成员函数。对静态成员函数的引用使用所属的类名加作用域分辨运算符来限制,即“类名::”。
Eg: classStudent
{
private:
……
public:
static void init()
{
Student::count=0;
Student::sum=0;
}
Static float average();
};
float student::average()
{
cout<<”sum is ”<<sum<<“\tcount is ”<<count<<endl;
cout<<”average is”<<sum/count<<endl;
return sum/count;
}
静态成员函数可以在创建该类的任何成员之前处理静态数据成员,这是普通成员函数不能实现的。一般来说,类的静态成员函数是用来访问静态数据成员的,当然可以访问全局变量。静态成员函数不具有this指针。也就是说,静态成员函数不与某个具体的对象相联系,它只属于该类。
【8】类的友元
1:友元函数:将关键字friend放在函数名的前面就将该函数说明为友元函数。一个类的友元函数是在该类中说明的一个非成员函数,但允许访问该类对象的所有成员。友元函数可以访问类的私有成员,节省了调用成员函数的开销,从而提高了程序的运行效率。如果需要一个函数同时访问多个类,则它可以定义为多个类的友元函数。1)使用友元破坏了封装性,降低了程序的可维护性。因此使用友元时要慎重的权衡得失后再决定。2)因为友元函数不是类的成员,故在友元函数中没有this指针,因此必须通过函数参数来传递对象。
2:友元类:若一个类为另一个类的友元,则次类的所有成员函数都能访问对方类的私有成员。下例所示:类B的所有成员函数都是类A的友元函数,都能够访问类A的所有成员。但是类A不是类B的友元类
Eg:class A
{
……
public:
friend class B;
……
};
-
-
类和对象、定义类、创建对象
2018-07-09 19:35:00类和对象面向对象编程的2个非常重要的概念:类和对象对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类类就相当于制造飞机时的图纸,用它... -
Python学习笔记(九):类和对象
2021-02-10 01:16:44Python学习笔记(九):类和对象 关于类和对象Python学习笔记(九):类和对象一.类和对象类的定义类的实例化类对象的使用二.self用法三.类方法实例方法类方法静态方法静态方法和类方法的区别四.类命名空间 一.类和... -
类和对象 子类父类
2018-06-24 13:31:59实例化对象 实例化对象格式 对象变量 = 类() 类的类型为 type <class 'type'> 类的值就是类本身 <class '__main__.Person'&...检测类和对象的成员 检测类成员 类名.__dict__ 检测对象成员 对象._... -
Scala进阶_类和对象
2020-02-16 11:45:56类和对象 scala是支持面向对象的,也有类和对象的概念。我们依然可以基于scala语言来开发面向对象的应用程序。 创建类和对象 用法 使用class来定义一个类 使用new来创建对象 示例 创建一个Person类,并创建它... -
Python学习笔记(十一):类和对象
2021-02-11 00:10:46Python学习笔记(十一):类和对象 关于类和对象Python学习笔记(十一):类和对象一.类变量和实例变量类变量实例变量二.函数装饰器带参数的函数装饰器函数装饰器的嵌套三.property()四.封装机制五.继承机制 一.类... -
C++类和对象的使用之对象指针
2019-07-04 21:38:07类和对象的使用之对象指针 对象指针的一般概念 对象指针:指向类的成员的指针。在C++中,可以说明指向类的数据成员和成员函数的指针。 对象指针遵循一般变量指针的各种规则:类名 *对象指针名; 对象指针名*成员名;... -
Python学习笔记(十二):类和对象
2021-02-12 21:20:21Python学习笔记(十二):类和对象 关于类和对象Python学习笔记(十二):类和对象一.父类方法重写类变量二.调用父类的构造方法super()三. __slots__四.动态创建类type() 一.父类方法重写 类体中、所有函数之外:此... -
JAVA 类和对象的实例
2019-01-15 11:01:23JAVA 类和对象的实例 什么是类? 1. 类是具有相同的属性和功能的事物的抽象的集合,在面向对象程序设计中,人们把一类事物的静态属性和动态可以执行的操作组合在一起就得到类这个概念。 2. 类是个抽象的概念,用来... -
python中的类和对象,属性和方法
2018-04-26 13:18:30一、面向对象的概述面向对象是一种描述业务问题、设计业务实体和实体之间关系的方法二、类和对象1、类和对象得区别:类是对客观世界中事物得抽象,而对象是类实例化后的实体 例如:汽车模型就是一个类,制造出来的... -
php面向对象——类和对象
2016-04-20 20:43:07php面向对象——类和对象1.类和对象 //定义一个类: class A{ public $name="John"; //定义一个普通属性 static $age=18; //定义一个静态属性 const PI=3.14; //定义一个常量 /*定义一个普通方法*/ -
Java类和对象 详解(二)
2016-10-07 17:52:38上一篇Java类和对象 详解(一)讲解了类和对象的基本概念,定义和使用,以及对象引用传递的初步分析,下面接着来讲其他内容。一、面向对象的封装性封装(encapsulation)又叫隐藏实现(Hiding the implementation)。... -
C++类和对象(下)——初始化列表、static成员和友元
2021-03-08 09:23:18C++类和对象——初始化列表、static成员和友元一、再谈构造函数1.1 构造函数整体赋值1.2 初始化列表三级目录 关于C++类和对象的学习 C++类和对象(上)——类的基本概念、类的限定符及封装和类成员函数的this指针 C++... -
Python类和对象的理解
2018-12-12 19:48:43理解类和对象的关系 类好比制造飞机的图纸,对象好比飞机实例。需要注意的是类中有的属性和方法,在对象中也有,并且不能多也不能少 类的定义: class 类名: #大驼峰命名发 def 方法1(self ,参数列表) ... -
C++类和对象的概念
2018-06-10 17:31:13C++类和对象的概念 面向对象程序设计 概念:(Object Oriented Programming,缩写:OOP)是一种程序开发的方法。 对象指的是类的实例,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、... -
Java中类和对象的概念
2018-06-01 23:50:23首先说说类和对象。今天心情不错,来复习复习Java基础:类和对象。Java是什么?Java是一门面向对象的编程语言(OOP),想要理解Java,首先要理解类(Class)和对象(Object)这两个概念。Java中的类可以看成C语言的... -
Java中的基本操作单元 - 类和对象
2020-02-26 18:51:25说到类和对象,这都是两个比较抽象的词,如果用在程序中,那就更不知道是什么意思了。其实大家可以先不联系程序,我们在对一大堆东西分类的时候自然是有一个标准的,符合某些特征的分到一类,符合另外一些特征的分到... -
面向对象的程序设计Java-类和对象
2017-02-21 15:11:20对象(Object) 对象具有两方面的含义 在现实世界中: 是客观世界中的一个实体 在计算机是中: 是一个可标识的存储区域 ...PS:类和对象有时都统称“对象”,为了明确起见,后者称为“对象实例” 例如 -
Java类和对象知识点的整理
2019-04-14 18:00:01通过学习视频,特意写下此次博客。本次博客目的是为了...一、类和对象 1.面向对象 (1)面向对象的理解 面向对象是已对象为基础,完成各种操作主要强调对象。 (2)面向对象的特点 面向对象是一种常见的思想,... -
动态给类和对象添加属性和方法
2017-10-20 15:09:30动态给类和对象添加属性和方法动态给类和对象添加属性定义一个Person类class Person(object): def __init__(self, name): self.name = name给对象添加属性 # 创建2个Person,分别为p1,p2p1 = Person('amy') print... -
类和对象举例
2019-03-05 14:11:28以狗为例,狗本身是一个对象 它属于动物类,动物类这个东西不存在,而狗这个物体存在,所以对象就是类的实体化,对象就是类的抽象化,类描述一类对象的行为和状态。举几个例子 人是一个类 具体的某个人就是对象 他的...