
类
JiBeon
这个作者很懒,什么都没留下…
展开
-
类的抽象、封装、数据隐藏
抽象通过类方法的共有接口对类对象执行操作。封装实现的具体细节(如数据表示和方法的代码)都是隐藏的。数据隐藏类的数据成员可以使私有的(默认),这意味着只能通过成员函数来访问这些数据。...转载 2019-06-17 09:48:00 · 2009 阅读 · 0 评论 -
继承和动态内存分配
1、派生类不使用new:此时不需要为派生类定义显式析构函数、复制构造函数和赋值运算符。2、派生类使用new:此时需要为派生类定义显式析构函数、复制构造函数和赋值运算符。基类中使用了动态内存分配:class baseDMA{private: char * label; int rating;public: baseDMA(const char * l="null", int r...原创 2019-06-18 21:11:01 · 308 阅读 · 0 评论 -
抽象基类和纯虚函数
纯虚函数在一个虚函数的声明语句后加上=0,就可以将一个虚函数变成纯虚函数。纯虚函数只用声明,而不能在类中定义,但要求任何派生类中都要定义自己的实现方式。其存在就是为了提供接口。抽象基类(ABC)引入原因:为了方便实现多态;有时基类本身生成对象是不合理的。定义:包含纯虚函数的类叫做抽象基类,不能创建该类的对象,只能用作基类。抽象基类不能用作参数类型、函数返回类型。但是可以声明指...原创 2019-06-18 20:32:31 · 193 阅读 · 0 评论 -
动态联编和静态联编
程序调用函数时,将函数调用解释为执行特定的函数代码块被称为函数名联编。在编译过程中进行联编被称为静态联编,又称为早期联编。然而,虚方法使得这项工作变得更困难,使用哪个函数不能在编译时确定,因为编译器不知道用户将选择哪个类型的对象。在程序运行阶段进行联编被称为动态联编,又名晚期联编。编译器对虚方法使用动态联编。...原创 2019-06-18 18:05:33 · 363 阅读 · 0 评论 -
访问控制权限protected
关键字protected与private相似,在类外只能通过公有类成员才能访问。对于派生类:派生类的成员可以直接访问protected成员,但不能直接访问private成员。因此,对外部世界来说,保护成员的行为与私有成员类似;对于派生类来说,保护成员行为与公有成员类似。...转载 2019-06-18 17:21:26 · 264 阅读 · 0 评论 -
派生类和基类
OOP的主要目的之一是实现代码可重用。类继承从已有的类派生出新的类,而派生类继承了原有类(基类)的数据成员和方法。派生类不能直接访问基类的私有成员,必须通过基类方法进行访问。因此,派生类构造函数必须使用基类构造函数(通过成员初始化列表)。派生类和基类之间的特殊关系派生类对象可以使用基类的方法,条件是方法不是私有的。基类指针可以在不进行显式类型转换的情况下指向派生类对象。基类引用可...原创 2019-06-18 14:40:31 · 1632 阅读 · 0 评论 -
成员初始化列表
成员初始化列表由逗号分隔的初始化列表组成(前面带冒号)。它位于参数列表的右括号之后、函数体左括号之前。这种格式只能用于构造函数。必须用这种格式初始化非静态const数据成员(C++11之前)1;必须用这种格式初始化引用数据成员2。class Agency {...};class Agent{private: Agency & belong; //引用数据成员 ......原创 2019-06-17 21:22:03 · 493 阅读 · 0 评论 -
类中嵌套结构和类
在类声明中声明的结构、类或枚举被称为是被嵌套在类中,其作用域为整个类。这种声明不会创建一个数据对象,而是指定可以在类中使用的类型。如果在private中嵌套,只能在类中使用它。如果在public中嵌套,可以通过类加作用域解析运算符的方式调用。...原创 2019-06-17 21:06:07 · 410 阅读 · 0 评论 -
返回对象与引用的说明
如果方法或函数要返回局部变量,则应该返回对象,而不是指向对象的引用,因为在被调用函数执行完毕时,局部对象将调用其析构函数。如果方法或函数要返回一个没有公有复制构造函数的类(如ostream)的对象,必须返回一个指向这种对象的引用。有些方法和函数(如重载的赋值运算符)可以返回对象,也可以返回指向对象的引用。在这种情况下,应首选引用,因为其效率更高。...原创 2019-06-17 20:11:13 · 707 阅读 · 0 评论 -
复制构造函数和深度复制
浅复制和深度复制浅复制:仅复制指针值,新的指针和原来的指针指向同一地址,执行析构函数会释放同一内存单元两次,造成悬挂指针。深度复制:通过将副本地址赋给新成员,复制指向的数据。复制构造函数如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而仅仅是指针。复制构造函数用于将一个对象复制到新创建的对象中,因此,它用于初始化过程中(包括按值传递参数),而不是...原创 2019-06-17 19:02:01 · 263 阅读 · 0 评论 -
类的自动类型转换和强制类型转换
某种类型转换为类类型定义接受一个参数的构造函数可用来将与该参数相同的类型转换为类类型,如:Stonewt(double lbs);因此,可以这样编写代码:Stonewt myCat;myCat=19.6; //使用Stonewt(double)将19.6转换为Stonewt类型这里,使用构造函数Stonewt(double)创建一个临时的Stonewt对象,并将19.6作为初始化值...原创 2019-06-17 15:56:34 · 659 阅读 · 0 评论 -
运算符重载(运算符函数)
重载在同一个作用域内的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。重载指多个函数或方法具有相同的名称、不同的参数列表和定义。调用一个重载函数或重载运算符时,编译器把所使用的的参数类型与定义中的参数类型进行比较,决定选用最合适的定义,被称为重载决策。运算符重载重载的运算符是电邮特殊名称的函数,函数名是关键字operator和其后要重载的运算符符号构成的。所以,运算符重载是...原创 2019-06-17 10:18:03 · 1601 阅读 · 0 评论 -
作用域为类的常量
在类内定义的数据成员和成员函数,其作用域为整个类,即只在该类中是可知的,在类外是不可知的。使符号常量的作用域为整个类,常规的变量声明方法不可行,class Bakery{private: const int Months=12; //不可行 double costs[Months]; ...因为声明类只是描述了对象的形式,并没有创建对象。因此,在创建对象前,将没有用于存储值的空间...原创 2019-06-16 22:56:23 · 210 阅读 · 0 评论 -
const关键字对成员函数的影响
对函数参数的修饰输入参数“按值传递”:函数将产生临时变量(局部变量),复制该参数并压入函数栈,故访问的是函数栈中的临时变量,原变量无需保护,不需要加const修饰。输入参数“指针传递”:函数内部虽然改变不了指针变量保存的指针值,但该指针却指向原值的地址,孤儿能修改原值。加const修饰可以防止意外地改动该指针指向的原值。输入参数“按引用传递”:a)引用只是变量的一个别名,引用指向原变量内存...转载 2019-06-16 22:32:35 · 142 阅读 · 0 评论 -
类的特殊成员函数
默认构造函数复制构造函数复制赋值运算符析构函数C++11新增:移动构造函数移动赋值运算符原创 2019-06-16 16:48:53 · 324 阅读 · 0 评论 -
Lambda函数(C++11)
基本概念用于创建匿名函数,lambda函数都是内联函数。bool f3(int x) { return x % 3 == 0; }[] (int x) {return x % 3 == 0; }使用[]代替了函数名;没有声明返回类型。仅当lambda表达式完全由一条返回语句组成时,自动类型推断才管用;否则,需要使用返回类型后置语法声明返回类型:[] (double x) -> ...原创 2019-06-16 16:42:42 · 433 阅读 · 0 评论 -
可变参数模板(C++11)
定义可变参数模板可以创建参数数量可变的模板函数和模板类。模板参数包、函数参数包参数包的定义C++11中,可使用一个用省略号表示的元运算符来声明模板参数包。template<tpyename...Args> //Args是模板参数包void show_list(Args...args> //args是函数参数包展开参数包将省略号放在参数参数包名的右...原创 2019-06-16 15:40:36 · 204 阅读 · 0 评论 -
什么不能被继承
构造函数继承意味着派生类对象可以使用基类的方法,然而,构造函数在完成其工作之前,对象并不存在。创建派生类对象时,必须调用派生类的构造函数,派生类的构造函数必须使用成员初始化列表语法来调用基类构造函数,以创建派生对象的基类部分。析构函数在释放对象时,程序首先调用派生类的析构函数,然后调用基类的析构函数。通常,对于基类,其析构函数应设置成虚的。赋值运算符因为派生类继承的方法的特征...原创 2019-06-18 22:01:19 · 426 阅读 · 0 评论 -
C++实现代码重用
公有继承包含(组合、层次化)私有or保护继承类模板原创 2019-06-20 21:07:56 · 469 阅读 · 0 评论 -
友元
通常,类的共有方法提供了对类对象私有部分唯一的访问途径。友元有三种:友元函数友元类友元成员函数友元函数友元函数在类的声明中声明,在声明前加上friend关键字。friend Time operator*(double m, const Time & t);虽然operator*()函数是在类声明中声明的,但它不是成员函数,因此不能使用成员运算符来调用;虽然opera...原创 2019-06-17 10:46:13 · 131 阅读 · 0 评论 -
多重继承与虚基类
MI描述的是有多个直接基类的类。注意:公有继承必须使用关键字public限定每一个基类,因为默认为private。class SingWaiter : public Waiter, public Singer {...};MI面临的问题:从两个不同的基类继承同名的方法;从两个或更多相关基类那里继承同一个类的多个实例。菱形继承问题:当多重继承的两个父类有共同的祖先时,...原创 2019-06-21 17:14:44 · 337 阅读 · 0 评论 -
使用using重新定义访问权限(私有/保护继承)
使用私有or保护继承时,基类的公有成员将成为私有成员or保护成员,不能像公有继承那样,可以直接使用基类方法。要达到这个目的,有两种方法:定义一个使用该基类方法的派生类方法使用using重新定义访问权限。使用一个using声明来指出派生类可以使用特定的基类成员,即使采用的是私有派生。class Student : private string, private valarray<...原创 2019-06-20 23:01:19 · 570 阅读 · 0 评论 -
私有继承
实现has-a关系的途径:包含(组合、层次化):类成员本身是另一个类的对象。私有继承。保护继承。私有继承在派生时,使用private关键字而不是public来定义类。class Student:: private string, private valarray<double> {...};使用私有继承,基类的公有成员和保护成员都将称为派生类的私有成员。这意味着基...原创 2019-06-20 22:45:51 · 731 阅读 · 0 评论 -
接口和实现
使用公有继承时,类既可以继承接口,也可以继承实现。(例外:纯虚函数只有接口没有实现)。使用组合1时,类可以获得实现,但不能获得接口。组合又称包含、层次化,实现has-a关系,详见 ↩︎...原创 2019-06-20 19:53:07 · 480 阅读 · 0 评论 -
模板类和友元
模板的友元分3类:非模板友元;约束模板友元,即友元的类型取决于类被实例化时的类型;非约束模板友元:即友元的所有具体化都是类的每一个具体化的友元。非模板友元函数友元函数没有类型参数:template <class T>class HasFriend{public: friend void counts(); ...};上述声明使counts()函数成...原创 2019-06-22 15:32:49 · 1007 阅读 · 0 评论 -
模板的实例化与具体化
实例化:模板本身不会生成函数或类定义,它只是一个用于生成函数或类的方案,编译器使用模板为特定类型生成函数或类定义的过程叫做模板的实例化。具体化:为模板中抽象的泛型指定具体的类型。它包含隐式实例化、显示实例化、显式具体化、部分具体化。隐式实例化:编译器使用通用模板提供的处方生成具体的类定义,声明一个对象,指出所需的类型。编译器生成对象之前,不会生成类的隐式实例化:ArrayTP&...原创 2019-06-22 11:27:12 · 2900 阅读 · 1 评论 -
类模板
模板是一种泛型编程思想,提供参数化类型,即能够将类型名作为参数传递给接收方来建立类或函数(形式、功能相似,类型不同),也是一种实现代码重用的重要方式。类模板定义类模板在class上一行使用template加尖括号声明:template<typename 类型参数1, typename 类型参数2,...>class 类名{...};当模板被调用时,参数类型将被具体的类型...原创 2019-06-21 23:00:35 · 267 阅读 · 0 评论 -
递归使用模板
对于二位数组定义:ArrayTP< ArrayTP<int,5>, 10 > twodee;使得twodee是一个包含10个元素的数组,其中每个元素都是一个包含5个int元素的数组。与之等价的常规数组声明如下:int twodee[10][5];注意:在模板语法中,维的顺序与等价的二维数组相反。...原创 2019-06-21 23:00:19 · 827 阅读 · 0 评论 -
类模板表示数组中元素数量的两种方式
模板常用作容器类,为容器类提供可重用代码是引入模板的主要动机。允许指定数组大小的方法:在类中使用动态数组和构造函数参数来提供元素数目(如模板类vector)template<class Type>class Stack{private: enum{SIZE = 10}; int stacksize; Type * items;public: explicit ...原创 2019-06-21 22:56:15 · 560 阅读 · 0 评论 -
关于构造函数
使用构造函数两种使用构造函数的初始化方式:Stock food = Stock("World", 250, 1.25);等价于:Stock garment("Furry", 50, 2.5);将构造函数与new一起使用:(new可以调用构造函数)Stock *pstock = new Stock("Electroshock", 18, 19.0);通过构造函数赋值构造...原创 2019-06-16 22:04:47 · 305 阅读 · 0 评论 -
总结:C++面向对象的三大特性——封装、继承、多态
传统的面向过程编程,数据以及对数据进行操作的函数都是分离的独立个体。OOP提供了将数据和方法整合起来的途径——类和对象。对象是类的实体,使程序更模块化,提升了代码重用水平。封装封装的思想是将内部细节和使用方式分开,把实现的细节隐藏,只暴露公有的接口,实现代码的模块化。C++通过访问标志符(private、protected、public)实现类的封装——将数据声明为private,只能通过...原创 2019-06-19 14:42:37 · 886 阅读 · 0 评论 -
虚函数virtual与多态
多态:希望同一个方法在派生类和基类中的行为是不同的,即方法的行为取决于调用该方法的对象。这种行为被称为多态——具有多种形态。实现多态公有继承的两种方式:在派生类中重新定义基类方法。使用虚方法。虚函数virtual虚方法的用途示例假设要创建一个数组来保存基类对象和派生类对象,但数组中所有元素的类型必须是相同的。可以创建指向基类的指针数组,这样,每个元素的类型都相同,但由于使用的...原创 2019-06-18 17:11:15 · 442 阅读 · 0 评论 -
静态类成员函数
在成员函数的声明前加关键字static,将其声明为静态的。不能通过对象调用静态成员函数,应使用类名和作用域解析运算符来调用它。静态成员函数只能使用静态数据成员,因为静态成员函数不与特定的对象相关联。...原创 2019-06-17 19:25:36 · 311 阅读 · 0 评论 -
单例模式(单例类)
单例模式是为了保证单例类的实例只有一个:一台计算机连接多台打印机的例子可以很好解释单例模式的用途;对于有些工具性质的类,基本不用存储太多跟自身有关的数据,在这种情况下每次都去new一个对象会增加开销,造成代码臃肿。其实,只需要一个实例就可以。定义一个单例类:使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法1来获取该实例。#include<iostream...原创 2019-07-02 14:21:34 · 289 阅读 · 0 评论 -
智能指针
智能指针是行为类似于指针的类对象,智能指针包含在头文件<memory>中动态内存管理经常出现的问题:忘记释放内存造成内存泄漏;尚有指针引用就释放,造成引用非法内存的指针。智能指针可自动释放所指向的对象。智能指针包括:auto_ptr、unique_ptr、shared_ptrauto_prt:C98++提供,但已被C++11摒弃。unique_ptr:建立所有...原创 2019-06-26 22:24:07 · 143 阅读 · 0 评论 -
委托构造函数(C++11)
在一个构造函数的定义中,以成员初始化列表的方式使用另一个构造函数,这被称为委托。可以避免重复编写多个重复构造函数中相同的代码,让编码工作更简单、更可靠。class Notes{ int k; double x; string st;public: Notes(); Notes(int); Notes(int, double); Notes(int, double, string...原创 2019-06-16 17:01:54 · 273 阅读 · 0 评论