-
2021-03-10 10:33:17
结构化程序设计
结构化程序设计的概念:是进行以模块功能和处理过程设计为主的详细设计的基本原则。结构化程序设计是面向过程程序设计的一个子集,它对写入的程序使用逻辑结构,使得理解和修改更有效更容易。
结构化程序设计的基本结构:
结构化程序是由若干个基本结构组合而成,每一个结构可以包含若干条语句和其他基本结构。结构化程序设计中包含三种基本的结构:顺序结构、选择结构和循环结构。
- 顺序结构:表示程序中的各操作是按照它们出现的先后线性,有序地执行。顺序结构的程序又称简单程序,这种结构的程序是顺序执行的,无分支,无转移,无循环,程序本身的逻辑很简单,它只依赖于计算机能够顺序执行指令的特点,依次执行个语句模块。
- 选择结构:表示程序的处理步骤出现了分支,它需要根据某一特定的条件选择其中的一个分支执行,选择结构有单选择、双选择和多选择三种形式。
- 循环结构:循环结构表示程序反复执行某个或某些操作,直到某条件为假(或为真)时才可终止循环。在循环结构中最主要的是:什么情况下执行循环?哪些操作需要循环执行?循环结构的基本形式有两种:当型循环和直到型循环。
结构化程序设计的不足:随着程序规模的扩大,难以理解、难以扩充、难以查错、难以重用。
- 在结构化程序设计中,函数和其所操纵的数据结构没有直观的联系。
- 程序理解难度与程序规模正相关:随着程序规模的增加,函数与被操作的数据结构之间的关系难以理解;函数之间的调用关系难以理解。
- 程序维护和扩充难度大:在结构化程序设计中没有封装和隐藏的概念,使得数据结构的变量都可以被直接访问,一旦发生改动,要修改所有变量访问语句。
- 错误发现难度大:数据结构和函数之间的复杂关系使得当数据结构中值出错时,难以找到发生错误的函数。
- 代码可重用率低:随着程序规模的扩大,由于函数和变量之间错综复杂的关系,很难抽取出整块代码进行重用。
面向对象的程序设计
面向对象的程序设计方法:客观事物的抽象过程
- 归纳客观事物的属性:将某类客观事物的共同特点归纳出来,形成一个数据结构,可以用多个变量描述事物的属性。
- 归纳客观事物的行为:将该类客观事物所能进行的行为也归纳出来,形成多个函数,这些函数可以用来操作数据结构。
面向对象程序设计的封装:通过某种语法形式,将客观事物抽象的数据结构和对应操作的函数捆绑在一起,形成一个类 (class),从而使得数据结构和操作函数呈现出清晰的关系,这称为封装。
面向对象程序设计的四个特点:抽象、封装、继承、多态
抽象出类的一个简单例子:计算矩形的周长和面积
矩形的属性:长和宽,可以用两个变量表示
矩形的行为:1. 设置长和宽的值 2. 计算周长 3. 计算面积 这三种行为可以分别使用一个函数来实现
矩形类:将上述矩形属性和行为封装在一起就形成了一个矩形类,长、宽变量称为该类的成员变量,三个函数称为该类的成员函数
class Rectangle{ public: int width, height; void Init(int width_, int height_){ width = width_; height = height_; } int Area(){ return width * height; } int Perimeter(){ return 2*(width + height); } };
通过类定义对象:C++ 中类的名字就是用户自定义类型的名字,使用方式和基本数据类型一样,通过类定义出来的变量,也成为类的实例即为对象。
int main(){ int w,h; Rectangle rec; // 声明一个对象 rec cin >> w >> h; rec.Init(w,h); cout << rec.Area() << endl << rec.Perimeter(); // 用指针访问对象成员 Rectangle r1, r2; Rectangle* p1 = &r1; Rectangle* p2 = &r2; p1->w = 6; p2->Init(5,4); // 用引用访问对象成员 Rectangle r3; Rectangle &rr = r3; rr.w = 6; rr.Init(5,4); return 0; }
对象的内存空间分配:对象所占用的内存空间大小等于所有成员变量的大小之和,成员函数不占用对象的内存空间,类的成员函数被所有对象共享。
类的定义
类的成员函数和类的定义分开:
class Rectangle{ public: int width, height; void Init(int width_, int height_){ width = width_; height = height_; } int Area(); int Perimeter(); }; // :: 声明函数属于类成员 int Rectangle::Area(){ return width * height; } int Rectangle::Perimeter(){ return 2 *(width + height); }
类成员的可访问范围:
在类的定义中,用关键字说明类成员可被访问的范围:
- private: 私有成员,可以被该类中的成员函数、友元函数访问,但不可以被子类的成员函数和该类的对象访问;
- 如果声明不写 public、protected、private,则默认为 private;
- 私有成员机制称为隐藏:目的在于强制对成员变量的访问一定要通过成员函数进行,这种机制使得在成员变量修改时,可以将修改范围缩小在成员函数中,而不需要修改整个项目中所有的成员变量访问语句。
- public:公有成员,可以被该类中的成员函数、子类的成员函数、友元函数访问,也可以由该类的对象访问,还可以被其他普通函数访问;
- protected:保护成员,可以被该类中的成员函数、子类的成员函数和友元函数访问,但不可以由该类的对象访问;
class Employee{ private: char szName[30]; public: int salary; int setName(char* name); int getName(char* name); void averageSalary(Employee e1, Employee e2); }; int Employee::setName(char* name){ strcpy(szName, name); } int Employee::getName(char* name){ strcpy(name,szName); } void Employee::averageSalary(Employee e1, Employee e2){ cout << e1.szName; salary = (e1.salary + e2.salary) / 2; } int main(){ Employee e; strcpy(e.szName, "Tom"); // 错误语句,szName是私有的,无法在类外访问 e.setName("Tom"); e.salary = 1000; // salary是公有的,可以类外访问 return 0; }
成员函数的重载与参数缺省:和普通函数一样,类的成员函数也是可以重载和进行参数缺省的,但是要注意避免二义性,详情参考从 C 到 C++:03 C++的函数 。
Reference
更多相关内容 -
C++类和对象详解
2019-03-25 18:00:301.类和对象的区别。 2.类的定义。 3.类的访问限定符和封装 4.类的作用域 5.类的实例化(用类类型创建对象) 6.计算类对象的大小 7.this指针 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用...类与对象上篇:
主要内容:
1.类和对象的区别。
2.类的定义。
3.类的访问限定符和封装
4.类的作用域
5.类的实例化(用类类型创建对象)
6.计算类对象的大小
7.this指针C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。1.类和对象的区别:
类是抽象的,不占用内存。
对象是具体的,占用内存。
类是对象的抽象,而对象是类的具体事项;
比如说:类是蔬菜,那么对象就是青菜等等。2.类的定义:
class className { // 类体:由成员函数和成员变量组成 }; // 一定要注意后面的分号
class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号。
类中的元素称为类的成员:类中的数据称为类的属性或者成员变量; 类中的函数称为类的方法或者成员函数。类的两种定义方式:
- 声明和定义全部放在类体中,需要注意:成员函数如果在类中定义。
- 声明放在.h文件中,类的定义放在.cpp文件中。
一般情况下,更希望大家采用第二种方式。
3.类的访问限定符及封装
类的访问限定符:
public
protected
private
说明:- public修饰的成员在类外可以直接被访问。
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的).
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
- class的默认访问权限为private,struct为public(因为struct要兼容C)。
经常会有面试题这样问大家:
问题:C++中struct和class的区别是什么?**答:**C++需要兼容C语言,所以C++中struct可以当成结构体去使用。另外C++中struct还可以用来定义类。和class是定义类是一样的,区别是struct的成员默认访问方式是public,class是struct的成员默认访问方式是private。
封装:
面向对象的三大特性:封装、继承、多态。封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
封装的本质就是一种管理:比如博物馆的文物,我们如何管理呢?首先是键一座房子把文物给封装起来。然后我们开放了售票通道。可以买票突破封装在和合理的监管机制下去参观。类也是一样,我们使用类数据和方法都封装到一下。不想给别人看到的,我们使用protected/private把成员封装起来。开放一些共有的成员函数对成员合理的访问。所以封装本质是一种管理
C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。4.类的作用域
- 每个类都定义了自己的作用域,类的成员(成员函数/成员变量)都在类的这个作用域内,成员函数内可任意访问成员变量和其它成员函数。
- 对象可以通过 . 直接访问公有成员,指向对象的指针通过 -> 也可以直接访问对象的公有成员。
- 在类体外定义成员,需要使用 :: 作用域解析符指明成员属于哪个类域。
class Person { public: void PrintPersonInfo(); private: char _name[20]; char _gender[3]; int _age; }; // 这里需要指定PrintPersonInfo是属于Person这个类域 void Person::PrintPersonInfo() { cout<<_name<<" "_gender<<" "<<_age<<endl; }
5.类的实例化
用类类型创建对象的过程称为类的实例化。class Person { public: void PrintPersonInfo(); private: char _name[20]; char _gender[3]; int _age; }; void Test() { Person man; man._name = "Peter"; man._age = 10; man._sex = "男"; man.PrintPersonInfo(); }
6.计算类对象的大小
看代码:
class A { public: void TestFunc() {} int _a; char _b; }; class B { public: void TestFunc() {} }; // 空类 class C {}; // 类大小的计算方式:类成员变量加起来 + 内存对齐 // 求结构体大小一模一样 // 空类和没有类成员变量的类的大小为一个字节 int main() { cout << sizeof(A) << endl; cout << sizeof(B) << endl; cout << sizeof(C) << endl; system("pause"); return 0; }
运行结果
结论:一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类(包括没有成员变量的类)的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。(比如如果现在给了C1,C2,C3三个空类,如果不给内存,那就无法区分这3个类)7 this指针
先定义一个日期类
class Date { public : void Display () { cout <<_year<< "-" <<_month << "-"<< _day <<endl; } void SetDate(int year , int month , int day) { _year = year; _month = month; _day = day; } private : int _year ; // 年 int _month ; // 月 int _day ; // 日 }; int main() { Date d1, d2; d1.SetDate(2018,5,1); d2.SetDate(2018,7,1); d1.Display(); d2.Display(); return 0; }
对于上述类,有这样的一个问题:
Date类中有SetDate与Display两个成员函数,函数体中没有关于不同对象的区分,那当s1调用SetDate函数时,该函数是如何知道应该设置s1对象,而不是设置s2对象呢?
C++中通过引入this指针解决该问题,即:C++编译器给每个“成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动编译器自动操作完成后:
class Date { public : void Display (Date* this) { cout <<this->_year<< "-" <<this->_month << "-"<< this->_day <<endl; } void SetDate(Date* this,int year , int month , int day) { this-> _year = year; this-> _month = month; this-> _day = day; } private : int _year ; // 年 int _month ; // 月 int _day ; // 日 }; int main() { Date d1, d2; d1.SetDate(2018,5,1); d2.SetDate(2018,7,1); d1.Display(); d2.Display(); return 0; }
this指针的特性:
- this指针的类型:类类型* const
- 只能在“成员函数”的内部使用
- this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
- this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递
关于this指针的一个面试题:
问题:下面程序能通过编译吗?如果崩溃,会在哪里奔溃?
class A { public: void PrintA() { cout<<_a<<endl; } void Show() { cout<<"Show()"<<endl; } private: int _a; }; int main() { A* p = nullptr; p->PrintA(); p->Show(); }
答案:能够编译通过,但会崩溃。因为p指向空,然后在运行类中的成员函数时,会通过p找到this指针。此时就会越界访问
未完待续!!!
-
c++类和对象
2019-01-13 15:26:38首先,明白c++和C语言的区别: C语言面向过程,c++面向对象; 面向过程:即我们着力于项目的每个过程... 由于c++面向对象的特点,类和对象就由此产生; 类:是抽象的一个类别; 对象:是类的实例化,相当于现实...首先,明白c++和C语言的区别:
- C语言面向过程,c++面向对象;
- 面向过程:即我们着力于项目的每个过程动作,实现每一个动作方法,分析出求解问题的步骤,通过函数调用逐步解决问题;
- 面向对象:即着力于对象,从对象个体出发,看对象的需求,将一件事情拆分成不同的对象,靠对象之间的交互完成;
- 由于c++面向对象的特点,类和对象就由此产生;
- 类:是抽象的一个类别;
- 对象:是类的实例化,相当于现实世界的实体;
类的实现:
- 将C语言中的struct进行延伸,c++中的struct可用来实现类;即可在struct内定义变量和函数;
struct Student { void SetStudentInfo(const string name, const string gender, int age) { strcpy(name, name); strcpy(gender, gender); age = age; } void PrintStudentInfo() { cout<<name<<" "<<gender<<" "<<age<<endl; } string name; string gender; int age; };
- 在c++中我们常用class来定义类
class Student { void SetStudent(const char* name, const char* gender, int age) { strcpy(_name, name); strcpy(_gender, gender); _age = age; } void PrintStudent() { cout<<_name<<" "<<_gender<<" "<<_age<<endl; } char _name[20]; char _gender[3]; int _age; };
类的访问限定符:
- public修饰的成员在类外可以直接被访问,public修饰的成员函数类内可访问public、protected、private修饰的成员;
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的),而类内protected修饰的成员函数不能访问public修饰的成员,private修饰的成员函数不能访问public、protected修饰的成员;
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止;
- class的默认访问权限为private,struct为public(因为struct要兼容C);
- 访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。
类的实例化:用类类型创建对象的过程,称为类的实例化
- 类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;
- 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量;
- 类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。
-
C++类和对象(下)——初始化列表、static成员和友元
2021-03-08 09:23:18C++类和对象(上)——类的基本概念、类的限定符及封装和类成员函数的this指针 C++类和对象(中)——类的6个默认成员函数(构造、析构、拷贝构造、赋值运算符重载) 一、再谈构造函数 1.1 构造函数整体赋值 在创建对象时...C++类和对象——初始化列表、static成员和友元
关于C++类和对象的学习
C++类和对象(上)——类的基本概念、类的限定符及封装和类成员函数的this指针
C++类和对象(中)——类的6个默认成员函数(构造、析构、拷贝构造、赋值运算符重载)
一、再谈构造函数
1.1 构造函数整体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。例如我们之前创建的Date类
class Date { public: Date(int year = 1900, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; };
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称作为类对象成员的初始化,构造函数体中的语句只能将其称作为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
1.2 初始化列表
<1>为什么有初始化列表?
对于我们定义的日期类,当类中出现以下成员时,如果只用构造函数则无法完成变量的初始化了,以下的成员变量需要在定义的时候就需要初始化
- 引用成员变量
- const成员变量
- 自定义类型的成员变量
其次对于自定义的类成员变量,不使用初始化列表会调用多次构造函数
<2> 如何使用初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
注意:每个成员变量在初始化列表中只能出现一次//1.2.2 class Time { public: Time(int hour = 1, int minute=1,int second = 1) :_hour(hour) ,_minute(minute) ,_second(second) { cout << "Time(int hour = 1, int minute=1,int second = 1)" << endl; } private: int _hour; int _minute; int _second; }; class Date { public: //初始化列表写法 Date(int year=1900, int month=1, int day=1,int hour=1,int minute=1,int second=1) :_year(year) ,_month(month) ,_day(day) ,_n(10) ,_ref(day) ,_t(hour,minute,second) { cout << "Date(int year, int month, int day,int hour,int minute,int second)" << endl; } private: int _year; int _month; int _day; //定义的时候需要初始化 int& _ref; //引用 const int _n; //const成员变量 Time _t; //自定义类型的成员变量 }; void Test2() { Date d1(2021,3,9,2,2,2); }
结果
<3> 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
如下代码的运行结果是什么?
//1.2.3 class A { public: A(int a) :_a1(a) , _a2(_a1) {} void Print() { cout << _a1 << " " << _a2 << endl; } private: int _a2; int _a1; }; void Test2() { A aa(1); aa.Print(); }
结果
1.3 explicit关键字
<1> 匿名对象
匿名对象顾名思义就是没有名字,其作用域只在一行中有效,例如下面的代码
//1.3.1 class B { public: B(int b = 0) :_b(b) { cout << "B(int b = 0)" << endl; } //析构函数 ~B() { cout << "~B()" << endl; } private: int _b; }; int main() { B bb(10); //生命周期在main函数域 B(2); //匿名对象生命周期在这一行 return 0; }
<2> 为什么有explicit关键字?
对于c++来说,构造函数不仅可以构造与初始化对象,对于单个参数的构造函数,还具有类型转换的作用。
当我们定义一个类进行初始化时,如果我们采取下面这种定义方式,编译器会自动生成一个匿名对象,然后用匿名对象对cc对象进行拷贝构造。
//1.3.2 class C { public: C(int c) :_c(c) { cout << "C()" << endl; } private: int _c; }; int main() { C cc(2); cc = 8; //编译器会自动生成一个匿名对象,然后用匿名对象对cc对象进行拷贝构造 return 0; }
<3> 如何使用explicit关键字?
用explicit修饰构造函数,将会禁止单参构造函数的隐式转换。
//1.3.3 class C { public: explicit C(int c) :_c(c) { cout << "explicit C(int c)" << endl; } private: int _c; }; int main() { C cc(2); cc = 8; //编译器会自动生成一个匿名对象,然后用匿名对象对cc对象进行拷贝构造 return 0; }
二、static成员
2.1 概念
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态的成员变量一定要在类外进行初始化。
面试题:实现一个类,计算程序中创建出了多少个类对象?这个时候我们就可以使用static成员变量和static成员函数来实现
//2.1 实现一个类,计算程序中创建出了多少个类对象。 class A { public: //构造函数 A() { ++_scount; } //拷贝构造函数 A(const A& a) { ++_scount; } static int GetAcount() { return _scount; } private: static int _scount; }; //初始化在类外 int A::_scount = 0; void TestA() { cout << A::GetAcount() << endl; A aa; A bb; A cc(bb); cout << A::GetAcount() << endl; }
2.2 特性
<1> 静态成员为所有类对象所共享,不属于某个具体的实例
<2> 静态成员变量必须在类外定义,定义时不添加static关键字
<3> 类静态成员即可用类名::静态成员或者对象.静态成员来访问
<4> 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
<5>静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值
Q1: 静态成员函数可以调用非静态成员函数吗?
不可以,因为静态成员函数没有隐藏的this指针
Q2:非静态成员函数可以调用类的静态成员函数吗?
可以,因为非静态成员函数含有this指针,指定了静态成员函数的类域
三、C++11的成员初始化新玩法
3.1 为什么?
对于C++98而言,类内自定义的内置类型,编译器会进行初始化,而其他内置类型不会,因此出现则会中初始化方法。
具体查看这篇博客的2.2.7节内容
C++类和对象(中)——类的6个默认成员函数(构造、析构、拷贝构造、赋值运算符重载)
3.2 怎么用?
C++11支持非静态成员变量在声明时进行初始化赋值,但是要注意这里不是初始化,这里是给声明的成员变量缺省值。
//3.C++11的成员初始化新玩法 class B { public: B(int b = 0) :_b(b) {} int _b; }; class A { public: void Print() { cout << a << endl; cout << b._b << endl; cout << p << endl; } private: // 非静态成员变量,可以在成员声明时给缺省值。 int a = 10; B b = 20; int* p = (int*)malloc(4); //静态成员不可以 static int n; }; int A::n = 10; int main() { A a; a.Print(); return 0; }
四、友元
- 友元分为:友元函数和友元类
- 友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用
4.1 友元函数
问题:现在我们尝试去重载operator<<,然后发现我们没办法将operator<<重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作数了。但是实际使用中cout需要是第一个形参对象,才能正常使用。所以我们要将operator<<重载成全局函数。但是这样的话,又会导致类外没办法访问成员,那么这里就需要友元来解决。operator>>同理
//4.1 class Date { public: Date(int year, int month, int day) : _year(year) , _month(month) , _day(day) {} ostream& operator<<(ostream& _cout) { _cout << _year << "-" << _month << "-" << _day; return _cout; } private: int _year; int _month; int _day; }; int main() { Date d(2017, 12, 24); d << cout; return 0; }
友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。//4.1 class Date { friend ostream& operator<<(ostream& _cout, const Date& d); friend istream& operator >> (istream& _cin, Date& d); public: Date(int year, int month, int day) : _year(year) , _month(month) , _day(day) {} ostream& operator<<(ostream& _cout) { _cout << _year << "-" << _month << "-" << _day; return _cout; } private: int _year; int _month; int _day; }; ostream& operator<<(ostream& _cout, const Date& d) { _cout << d._year << "-" << d._month << "-" << d._day << endl; return _cout; } istream& operator >> (istream& _cin, Date& d) { _cin >> d._year >> d._month >> d._day; return _cin; } int main() { Date d(2017, 12, 24); cout<<d; //Date d1; cin >> d; cout << d; return 0; }
4.2 友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
- 友元关系是单向的,不具有交换性。
比如下面Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。 - 友元关系不能传递
如果B是A的友元,C是B的友元,则不能说明C时A的友元。
class Date; // 前置声明 class Time { friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量 public: Time(int hour=0, int minute=0, int second=0) : _hour(hour) , _minute(minute) , _second(second) {} private: int _hour; int _minute; int _second; }; class Date { public: Date(int year = 1900, int month = 1, int day = 1) : _year(year) , _month(month) , _day(day) {} void SetTimeOfDate(int hour, int minute, int second) { // 直接访问时间类私有的成员变量 _t._hour = hour; _t._minute = minute; _t._second = second; } private: int _year; int _month; int _day; Time _t; };
五、内部类
概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。注意此时这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。
注意:内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
特性:
- 内部类可以定义在外部类的public、protected、private都是可以的。
- 注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名。
- sizeof(外部类)=外部类,和内部类没有任何关系
class A { private: static int k; int h; public: class B { public: void foo(const A& a) { cout << k << endl;//OK cout << a.h << endl;//OK } }; }; int A::k = 1; int main() { A::B b; b.foo(A()); return 0; }
-
C++类和对象(2013级-C++程序设计)
2014-03-09 13:57:022013级,C++程序设计课件。第8章 类和对象,内容 8.1 面向对象程序设计方法概述 8.2 类的声明和对象的定义 8.3 类的成员函数 8.4 对象成员的引用 8.5 类的封装性和信息隐蔽 8.6 类和对象的简单应用举例 -
C++类和对象(二)(2013级-C++程序设计)
2014-03-23 16:41:33第9章 C++类和对象(二),内容 9.1 构造函数 9.2 析构函数 9.3 调用构造函数和析构函数的顺序 9.4 对象数组 9.5 对象指针 9.6 共用数据的保护 9.7 对象的动态建立和释放 9.8 对象的赋值和复制 9.9 静态成员... -
C++类和对象数组
2018-05-14 23:47:15C++类和对象数组 【1】对象数组 1:对象数组的定义:类名 数组名[元素个数] Eg: student asa[10];//有10个元素的学生类对象数组 2:对象数组的访问形式:数组名[下标].成员名; Eg: asa[j].print(); 3:对象... -
C++类和对象的使用之对象指针
2019-07-04 21:38:07在C++中,可以说明指向类的数据成员和成员函数的指针。 对象指针遵循一般变量指针的各种规则:类名 *对象指针名; 对象指针名*成员名; 对象指针在使用之前,也一定要先进行初始化,让它指向一个已经声明过的对象,... -
C++类和对象的概念及定义
2018-07-07 19:59:12一. 什么是面向对象?1. 面向对象的定义 面向对象是软件开发的一种方法,它的主要思想就是:把整个世界看做是具有行为活动各种对象组成的。...将对象作为程序的基本单元,将程序和数据封装在其中,以提高... -
C++类和对象的概念
2018-06-10 17:31:13C++类和对象的概念 面向对象程序设计 概念:(Object Oriented Programming,缩写:OOP)是一种程序开发的方法。 对象指的是类的实例,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、... -
C++类和对象(一)
2022-07-12 21:46:57目录面向过程和面向对象初步认识类的定义类的作用域类的实例化类的访问限定符及封装类的对象大小计算类成员函数this指针 面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过... -
C++类和对象,结构体
2016-09-15 10:48:24C和C++规定可以用一个结构体,里面即可有数组,也可以有其他变量。C中成员只能是数据,C++除了数据,还可以是函数。 但是,C++提供了类这个东西,所以不需要包含函数的结构体。 1,结构体: #include using ... -
【C++】类和对象--public和private
2018-06-03 12:33:17这个例子就对类的建立和使用做了个大概的介绍: 首先是类的建立,需要声明它的属性,以及属性的性质,之后需要建立这个类内部的函数; 在使用这个类的时候,要实例化这个类,并且对类的属性初始化。 注意类的实例... -
class Sample{ private: int a; static int b; }; // sizeof(Sample) 的结果是 4 而不是 8
-
C++类和对象详解(new与不new的区别)
2016-10-17 15:03:40c++ 对象 声明类 创建对象 new -
【C++类和对象】计算两点间距离的两种方法
2019-01-10 20:49:10使用类的组合(线段Line类中包含点Point类成员): #include <iostream> #include <cmath> using namespace std; //Point类的定义 class Point { public: Point(int xx = 0, int yy ... -
C++类对象和类指针的区别
2019-04-17 20:57:28一篇转载率较高的帖子:C++ 类对象和 指针的区别 大佬都不贴结果。。。。所以这里我给出代码和结果: #include<iostream> using namespace std; class Test{ public: int a; Test(){ a = 1; } }; ... -
C++中类与对象的关系
2017-03-26 17:02:42C++是一门面向对象的编程语言,理解C++,首先要理解类(Class)和对象(Object)这两个概念。 C++中的类(Class)可以看做C语言中结构体(Struct)的升级版。结构体是一种构造类型,可以包含若干成员变量,每个... -
【C++】C++类的定义和对象的创建
2018-10-11 12:38:43每个对象都是类的一个具体实例(Instance),拥有类的成员变量和成员函数。 在面向对象的编程语言中,经常把函数(Function)称为方法(Method)。 class是 C++ 中新增的关键字,专门用来定义类。... -
C++类和对象概念
2016-08-06 20:13:06C++是一门面向对象的编程语言,理解C++,首先要理解类与对象这两个概念。 C++中的类可以看做C语言中结构体(Struct)的升级版。结构体是一种构造数据类型,可以包含若干成员(变量),每个成员的数据类型可以不... -
定义C++类对象的方法
2021-06-08 09:56:45定义C++类对象的方法 我们学习了类的定义,与C语言的struct结构体类型定义差不多。那么,C语言可以使用struct结构体类型来定义对象,那么,C++同样可以使用类来定义对象。 C++使用类来定义对象也可以有几种方法... -
C++类对象的赋值操作
2021-06-11 10:37:20注意,对象名1和对象名2必须属于同一个类。此时,对象名2的成员变量,赋值给对象名1中对应的成员变量。 修改上面的例子,把struct结构体修改为class类。然后,执行对象之间的赋值。程序测试代码如下: 程序运行结果... -
C++类的存储及类对象内存结构
2016-07-22 16:06:12c++中最重要的就是类,那么一个类的对象,它在内存中如何存储的?它占 内存中多少个字节? 首先确定类的构成: 1,数据成员:可以是内置类型,类类型。 2,函数成员:虚函数,非虚函数 1)数据成员 内置类型... -
C++ 类与对象
2012-09-06 13:58:30今天主要讲类的构成,成员函数以及对象的定义和使用。 1.其实这一节,对于用C#开发的人来说,简直就是驾轻就熟啊。C++类的构成,我想从C的结构体开始说起。C中的结构体我想大家在熟悉不过了。 1 #include ... -
C++ 类对象的初始化
2021-04-13 20:50:08类对象的初始化 序: 程序在使用时是常常需要对变量进行初始化赋值。与c语言不同,在面向对象的编程中,使用构造函数对数据成员进行初始化,有多种方式。 录: 一、无参数的构造函数 二、带参数的构造函数 三、使用... -
c++类成员对象
2018-06-11 18:00:52成员对象:当一个类的成员是另一个类的对象时,这个对象就叫成员对象。 成员对象的构造与析构 1、出现成员对象时,如果成员对象的构造函数是有参构造函数,则该类的初始化列表需要对成员对象进行初始化。 class ... -
C++类成员函数返回对象及返回引用
2021-11-22 15:54:40C++类函数返回类的对象及类的引用一、代码例题二、返回引用三、返回对象 一、代码例题 #include <iostream> using namespace std; class machine; ostream& operator<<(ostream& o,const ...