当前位置: 首页 > 编程日记 > 正文

C++基础知识(二)

八、

      继承:让某个类的对象获得另一个类的对象的特性。通过继承可实现代码重用,即从已存在的类派生出的一个新类将自动具有原来那个类的特性。

类的继承还具有:(1)单向性;A类为B类的基类(父类),则派生类(子类)B继承了父类A中的属性和方法,在B类中可访问A类的属性和方法,但在父类A中则不能访问子类的任何属性和方法。同时单向又体现为子类B继承了父类A,则A类不能再继承B类。(2)传递性;A类为B类的基类,B类为C类的基类,则基类A中的属性和方法通过子类B同时又传给了子类C,同理C类也不能作为A类的基类。(3)可重用性;通过继承,基类代码得到重用,而不用重写。

C++规定派生类中对象成员(其它类的对象)初值的设定应在初始化列表中进行,所以派生类的构造函数定义(派生类头文件中构造函数的声明格式与普通类相同)可写成:函数类型 派生类名::派生类名(形参表):基类1(参数表),基类2(参数表),...,基类n(参数表),对象成员1(参数表),对象成员2(参数表),...,对象成员n(参数表) {...}

在派生类数据成员通常有3类:继承于基类的数据成员派生类中自身定义的数据成员以及派生类中其它类的对象。在上述形式中,由于基类在派生类中常常是隐常的,所以通过调用基类构造函数来对基类的数据成员初值化,这也称为基类拷贝或基类子对象。在上述构造函数定义中的对象成员为派生类中定义的其它类的对象(构造函数中的形参初始化)

当然在初始化列表中也可对派生类自身数据成员初始化,但必须为“数据成员名(参数表)”形式。对于基类拷贝成员的初始化次序,若为单继承,优先初始化上层类的对象;若为多继承,则取决于派生类声明指定继承时的基类的先后次序,与初始化列表中的次序无关。对于派生类自身数据成员的初始化次序与初始化列表中的次序无关,取决于在派生类中声明的先后次序。

继承方式:公有继承(public),私有继承(private),保护继承(protected)

公有继承

       基类对象可访问基类公有成员,不可访问保护成员和私有成员。

派生类成员可访问基类的公有成员和保护成员,它们作为派生类的成员时,保持原来的状态;若在派生类中有同名成员存在,则访问基类成员时,基类成员名前面必须加上“基类名::”来指定成员所属的类;派生类成员不可访问基类的私有成员。

派生类对象只能访问基类的公有成员,不可访问保护成员和私有成员;对于同名成员,在基类成员名前面加上“基类名::”来指定成员所属的类,如OB.OA::m或OB-> OA::m。

总之,公有继承时,基类对象与派生类对象可访问基类的公有成员,而派生类的成员函数则可访问基类的公有成员和保护成员。

私有继承

基类对象可访问基类公有成员,不可访问保护成员和私有成员。

派生类成员可访问基类的公有成员和保护成员,它们作为派生类的成员时,作为派生类的私有成员,因此不能被这个派生类的子类所访问;若在派生类中有同名成员存在,则访问基类成员时基类成员名前面必须加上“基类名::”来指定成员所属的类;派生类成员不可访问基类的私有成员。

派生类对象不能访问基类任何成员(公有成员也不能访问)。

总之,私有继承时,基类对象可访问基类公有成员,派生类对象不能访问基类所有成员,而派生类的成员函数则可访问基类的公有成员和保护成员(但不能再往下继承)。

保护继承

基类对象可访问基类公有成员,不可访问保护成员和私有成员。

派生类成员可访问基类的公有成员和保护成员,它们作为派生类的成员时,作为派生类的保护成员(与私有继承的唯一区别),且不能被这个派生类的子类所访问;若在派生类中有同名成员存在,则访问基类成员时基类成员名前面必须加上“基类名::”来指定成员所属的类;派生类成员不可访问基类的私有成员。

派生类对象不能访问基类任何成员(公有成员也不能访问)。

总之,保护继承时,基类对象可访问基类公有成员,派生类对象不能访问基类所有成员,而派生类的成员函数则可访问基类的公有成员和保护成员(但不能再往下继承)。

多重继承与虚继承:虚继承是为解决多重继承而出现的,是多重继承中特有的概念。例如,类D继承于类B和类C,而类B和类C又都继承于类A,即A类是B类和C类的基类,而B类和C类同时是D类的基类。为了节省内存空间 ,可以将B,C对A的继承定义为虚拟继承,则A就成了虚拟基类。用代码表示如下:

class A ;

class B:public virtual A;//虚拟继承

class C:public virtual A;//虚拟继承

class D:public B,public C;

最后说明,在面向对象的程序设计中,继承和多重继承一般是指公共继承,很少用私有继承和保护继承

九、

    多态:允许将子类类型的指针赋值给父类类型的指针。多态性是通过虚函数实现的,是面向对象编程的核心概念。虚函数就是允许被其子类重新定义的成员函数,而子类重新定义父类虚函数的做法,叫做覆盖或重写。

覆盖是指子类重新定义父类的虚函数的做法。重写的函数必须有一致的参数表和返回值(C++标准允许返回值不同的情况,但很少有编译器支持)

重载是指编写一个与已有函数同名但参数表不同(个数或类型不同)的函数。即指允许存在多个同名函数, 但这些函数的参数表不同。重载的概念并不属于面向对象编程。它的实现是:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对编译器来说是这样的)。函数重载是静态联编的具体实现方式。调用重载函数时,编译根据调用时参数类型与个数在编译时实现静态联编,将调用地址与函数名进行绑定。所以说对于重载函数的调用,在编译期间就确定了,是静态的,也就是说它们的函数标识符与内存地址在编译期就绑定了(早绑定)。因此重载与多态无关

在静态联编的方式下,同一成员函数(参数类型及个数相同,函数返回类型也相同)在基类与派生类中的不同版本是不会在运行时根据程序代码的指定进行自动绑定的,必须通过类的虚函数机制,才能实现基类和派生类中的成员函数不同版本的动态联编。动态联编是指函数标识符与内存地址在程序运行时动态绑定,而不在编译时静态绑定,所以又称晚绑定。虚函数是用关键字virtual来修饰基类中的public或protected的成员函数。当在派生类中进行重新定义后(函数覆盖),就可在此派生类中具有该成员函数的不同版本。在程序运行过程中,依据基类对象指针所指向的派生类对象,或通过基类引用对象所引用的派生类对象,才能确定哪个派生类中重新定义的成员函数被激活,从而实现动态联编。虚函数虽然只是在一般函数定义前加上virtual,但必须是类中成员函数;可把析构函数定义为虚函数,但不能把构造函数定义为虚函数,通常在释放基类中及其派生类中动态申请的存储空间时,也要把析构函数定义为虚函数,以便实现撤销对象时的多态性;虚函数在派生类重新定义时,参数个数和类型以及函数类型必须和基类的虚函数完全匹配,这一点与函数重载完全不同;虚函数派生下去仍是虚函数,且可省略virtual关键字

当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态地调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(所调子类的虚函数的地址无法确定)。因此,这样的函数地址是在函数运行期间绑定的(晚绑定)。

基类与派生类中的每个虚函数都在虚函数表中(vtable)占有一个表项,保存着一条跳转到它的入口地址的指令(实际上就是保存它的入口地址)。当一个包含虚函数的对象(注意,不是指针类型对象)被创建时,它在头部附加一个指针,指向vtable中相应的位置。调用虚函数的时候,不管是用什么指针调用的,它先根据 vtable找到入口地址再执行,从而实现了动态联编。而普通函数只有简单地跳转到一个固定的地址

十、

只有类的成员函数才能访问类的私有成员,程序中的其它函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,不能访问其私有成员。

友元是一种定义在类外部的普通函数,但它需要在类中说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend友元不是成员函数,但它可以访问类中的私有成员。友元可以提高程序的运行效率。但是它破坏了类的封装性和隐藏性,使非成员函数也可以访问类的私有成员。友元可以是一个函数,称为友元函数;友元也可以是一个类,称为友元类。

十一、

     this指针:this指针是类中一个特殊指针,当类实例化(用类定义对象)时,this指针指向对象自己,而在类的声明时指向类本身。

十二、

    关于C++中class里面 static变量问题(即面向对象的程序设计中的static),与C中的static全局变量和局部变量含义不同(C是面向过程的程序设计)

class B:

{

public:

static int a;

};

B b;

int _tmain(int argc, _TCHAR* argv[])

{

b.a = 10;

system("pause");

return 0;

}

编译出现错误:

Error error LNK2001: unresolved external symbol "public: static int B::a"

解决方法:必须初始化,初始化的时候要在类外;如下:添加int B::a = 0;也可在类中初始化,在类中写成static int a=0;    

静态变量是属于类,而不是属于类对象的。也就是说不管你有多少个类对象,静态成员只有一个。 它的初始化,不能依赖于创建类对象时用于初始化对象的构造函数。

静态数据成员也遵从 public/private/protected访问规则。类中的那个static int a; 只是声明,定义要放在外面int B::a = 0; // 此处可以初始化 。如果a是公有的,B::a就可以访问了(读取和修改)。 静态成员的提出是为了解决数据共享的问题。实现共享有许多方法,如:设置全局性的变量或对象是一种方法。但是,全局变量或对象是有局限性的。在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员

使用静态数据成员可以节省内存,因为它是所有对象所公有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共用。因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它;

同全局变量相比,使用静态数据成员有两个优势:静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;可以实现信息隐藏,静态数据成员可以是private成员,而全局变量不能;

静态数据成员的使用方法和注意事项如下:

1、静态数据成员在定义或说明时前面加关键字static。

2、静态成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式如下:

<数据类型><类名>::<静态数据成员名>=<值>

这表明:

(1) 初始化可在类外进行,而前面不加static,以免与一般静态变量或对象相混淆。当然也可在类中初始化。

(2) 初始化时不加该成员的访问权限控制符private,public等。

(3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。

3、静态数据成员是静态存储的,它是静态生存期,必须对它进行初始化

4、引用静态数据成员时,采用如下格式:<类名>::<静态成员名>

如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员。

与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this 是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数和静态数据成员。而非静态成员函数(普通函数)可以访问静态数据成员和调用其余的静态成员函数。

关于静态成员函数,可以总结为以下几点:

1、出现在类体外的函数定义不能指定关键字static;

2、静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;

3、非静态成员函数可以任意地访问静态成员函数和静态数据成员;

4、静态成员函数不能访问非静态成员函数和非静态数据成员;

5、由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;

6、调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,

也可以直接使用如下格式:<类名>::<静态成员函数名>(<参数表>)调用类的静态成员函数。

转载于:https://www.cnblogs.com/King-Gentleman/p/4822425.html

相关文章:

Spring MVC 学习笔记 对locale和theme的支持

Spring MVC 学习笔记 对locale和theme的支持 Locale Spring MVC缺省使用AcceptHeaderLocaleResolver来根据request header中的 Accept-Language 来确定访客的local。对于前端jsp页面上&#xff0c;spring提供了标签<spring:message>来提供从resource文件中获取的文字的动…

iOS逆向(4)-代码注入,非越狱窃取微信密码

利用LLDB对微信进行分析&#xff0c;然后利用分析的结果&#xff0c;再逐步讲解如何Hook微信的登录过程&#xff0c;截获微信密码。 在上一篇文章(APP重签名)中&#xff0c;已经介绍了如何对APP重签名&#xff0c;并且利用XCode将微信跑起来&#xff0c;既然到了这一步&#xf…

java http请求 工具类_Java 实现 Http 请求工具类

1 packagecom.demo.util;23 importjava.io.BufferedReader;4 importjava.io.IOException;5 importjava.io.InputStreamReader;6 importjava.io.OutputStreamWriter;7 importjava.net.URL;8 importjava.net.URLConnection;910 public classHttpUtil {11 /**12 * 向指定URL发送GE…

Entity Framework学习三:查询、插入、更新和删除操作

1.LINQ过滤数据 var query from person in context.Peoplewhere person.FirstName.StartsWith("a")select person; var methodQuery context.People.Where(p > p.FirstName.StartsWith("a")); 两种不同的写法&#xff0c;效果一样。 多条件组合查找…

c/s开发基础自学纪录为主

1&#xff0e;常用属性 &#xff08;1&#xff09;Name属性&#xff1a;用来获取或设置窗体的名称。 &#xff08;2&#xff09;WindowState属性&#xff1a;用来获取或设置窗体的窗口状态。 &#xff08;3&#xff09;StartPosition属性&#xff1a;用来获取或设置运行时窗体的…

不错的威盾PHP加密专家解密算法

<?php /*********************************** *威盾PHP加密专家解密算法 http://www.my400800.cn ***********************************/ $filename"phpfilename.php";//要解密的文件 $lines file($filename);//0,1,2行 //第一次base64解密 $content"&quo…

java网络编程udp_java网络编程 UDP网络编程问题

为什么我的代码运行后&#xff0c;黑窗口&#xff0c;不显示一端发来的数据&#xff0c;而是黑窗口打印很多空格&#xff1f;请帮一下&#xff0c;初学者&#xff01;谢谢&#xff0c;下面是二个具有发送和接受功能的代码&#xff1f;发送端————importjava.net.*;imp...为什…

权限组件(10):三级菜单的展示和增删改查

效果图&#xff1a; 三级菜单的实现和一级、二级菜单差不多。需要注意的是增加三级菜单时&#xff0c;三级菜单是用户提交后在后台通过二级菜单的id添加的。 一、路由分发 rbac/urls.py ... from django.urls import re_pathfrom rbac.views import menu ...urlpatterns [...…

ROS知识(4)----初级教程之常见问题汇总

一、开机启动ROS的工作空间的路径设置失败 现象&#xff1a;在教程&#xff1a;http://wiki.ros.org/cn/ROS/Tutorials/CreatingPackage中的第5.1小节&#xff0c;运行以下命令失败&#xff1a; $ rospack depends1 beginner_tutorials 提示错误&#xff1a;[rospack] Error: …

sql server 海量数据速度提升:SQL优化-索引(11) 【转】

12、高效的TOP 事实上&#xff0c;在查询和提取超大容量的数据集时&#xff0c;影响数据库响应时间的最大因素不是数据查找&#xff0c;而是物理的I/0操作。如&#xff1a; select top 10 * from ( select top 10000 gid,fariqi,title from tgongwen where neibuyonghu办公室or…

java重定向带参数_急 求助重新封装重定向带参数问题

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼这是我写的代码 不知道行不行 求助package base.web.resolver.result;import java.util.HashMap;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.logging.log4j.…

Java程序员从笨鸟到菜鸟之(五)java开发常用类(包装,数字处理集合等)(下)...

本文来自&#xff1a;曹胜欢博客专栏。转载请注明出处&#xff1a;http://blog.csdn.net/csh624366188 写在前面&#xff1a;由于前天项目老师建设局的项目快到验收阶段&#xff0c;所以&#xff0c;前天晚上通宵&#xff0c;昨天睡了大半天&#xff0c;下午我们宿舍聚会&#…

对数组中的数字 1 和 2 进行排序,使得数字 1、2 分别位于前、后部分

问题描述&#xff1a;假设某个数组中只有数字 1 和 2&#xff0c;进行排序&#xff0c;使得数字 1 位于数组前部分&#xff0c;数字 2 位于后部分。 这道算法题其实不是很难&#xff0c;使用各种排序算法应该都能解出&#xff0c;但是若要考虑性能问题&#xff0c;那就得选择一…

@class和#import

class 作用&#xff1a; 可以简单的引用一个类 简单使用&#xff1a; class Dog; 仅仅是告诉编译器&#xff0c;Dog是一个类&#xff1b;并不会包含Dog这个类的所有内容 具体使用&#xff1a; 在.h文件中使用class引用一个类 在.m文件中使用#import包含这个类的.h文件 作用上的…

java登陆界面连接数据库_java 登陆界面怎么写,连接数据库后

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼界面是package 界面类;import javax.jws.soap.SOAPBinding.Use;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing…

C# 汉字编码GB2312转换

功能界面 源码&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace wordsConvert {public partial class Fo…

python批量爬取文档

最近项目需要将批量链接中的pdf文档爬下来处理&#xff0c;根据以下步骤完成了任务&#xff1a; 将批量下载链接copy到text中&#xff0c;每行1个链接&#xff1b;再读txt文档构造url_list列表&#xff0c;利用readlines返回以行为单位的列表&#xff1b;利用str的rstrip方法&a…

[Android]webview直接加载网页允许JS,进度条,当前应用内跳转

webview&#xff0c;用于在应用里面直接加载网页本代码参考了&#xff1a;官方的webview实例介绍&#xff1a;https://developer.android.com/guide/tutorials/views/hello-webview.html 加上进度条&#xff1a; http://blog.csdn.net/stoneson/article/details/6068089 整个源…

ubuntu 14.04 安装java_Ubuntu 14.04中安装Java

第三&#xff1a;在Ubuntu 和 Linux Mint上安装Java看了各种类型"java";的不同之后&#xff0c;让我们看如何安装他们。1)在Ubuntu和Linux Mint上安装JRE打开终端&#xff0c;使用下面的命令安装JRE&#xff1a;sudo apt-get install default-jre2)在Ubuntu和Linux M…

C# 生成系统唯一号

生成唯一号&#xff1a;思路&#xff0c;根据yymmddhhmmss自增长号唯一服务器号( SystemNo)生成唯一码&#xff0c;总长度19&#xff0c;例如&#xff1a;1509281204550000101. public class UniqueNumber{private static long num 0;//流水号private static object lockObj …

EBS上用过的一些接口表整理信息

AP接口表&#xff1a;AP_INVOICES_INTERFACEAP_INVOICE_LINES_INTERFACE涉及的请求&#xff1a;应付款管理系统开放接口导入涉及案例&#xff1a; 运费导AP、费用导APPO接口表&#xff1a;申请&#xff1a;PO_REQUISITIONS_INTERFACE_ALL涉及请求&#xff1a;导入申请采购&…

linux源码编译安装nginx

1.从nginx的官方网站下载nginx的安装源码包&#xff0c;要下载.gz格式的包才是linux安装包 网址http://nginx.org/download/ wget http://nginx.org/download/nginx-1.5.9.tar.gz 2.解压 tar -zxvf nginx-1.5.9.tar.gz yum -y install pcre-devel gcc gcc-c autoconf automak…

usr share里没有mysql_无法在ubuntu 12.04上安装mysql,找不到消息文件’/usr/share/mysql/errmsg.sys’...

尝试使用apt-get安装mysql但它失败了# apt-get install MysqL-serverReading package lists... DoneBuilding dependency treeReading state information... DoneThe following extra packages will be installed:MysqL-server-5.5Suggested packages:tinycaThe following NEW …

android:更改PagerTabStrip背景颜色,标题字体样式、颜色和图标,以及指示条的颜色...

1.更改PagerTabStrip背景颜色我们直接在布局中设置background属性可以&#xff1a;<android.support.v4.view.ViewPagerandroid:id"id/pager"android:layout_width"fill_parent"android:layout_height"fill_parent" ><android.support.…

敏捷开发日常跟进系列之二:燃尽图(中)

这是敏捷开发日常跟进系列的第二篇&#xff08;栏目目录&#xff09;。 迭代及燃尽图的目标 燃尽图的目标是完成迭代的目标&#xff0c;迭代的目标是什么呢&#xff1f; 1. 按产品经理的要求&#xff0c;交付计划会中计划的用户故事 2. 尽量完成1 之后还会看到&#xff0c;这个…

[python][jupyter notebook]之菜鸟安装[pyecharts]中Geo或Map显示问题

作为菜鸟&#xff0c;在学习使用pyecharts模块进入jupyter notebook的时候&#xff0c;又遇到了问题——那就是&#xff0c;可以使用一下代码&#xff0c;导入Geo和Map模块&#xff0c;但是弄了之后看不见地图。 from pyecharts import Geo from pyecharts import Map 所以&…

c语言多线程mysql_多线程读写mysql数据库

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼unsigned int __stdcall scan(PVOID pM){char ip[20];strcpy(ip, (char*)pM);MYSQL mysql;MYSQL_RES* result;//初始化mysql句柄mysql_init(&mysql);//连接mysql数据库if(!mysql_real_connect(&mysql,"localhost"…

[C#,Java,PHP] - IMAP文件夹名称编码和解码方法

[C#] 来源&#xff1a;http://www.oschina.net/code/snippet_110991_2237 // 编码private string IMAPEncode(string folder){string rtn "", base64;int index 0; Regex regAsis new Regex("\G(?:[\x20-\x25\x27-\x7e])"); Regex reg26 new Rege…

fzu 2150 Fire Game 【身手BFS】

称号&#xff1a;fzu 2150 Fire Game &#xff1a;给出一个m*n的图&#xff0c;‘#’表示草坪&#xff0c;‘ . ’表示空地&#xff0c;然后能够选择在随意的两个草坪格子点火。火每 1 s会向周围四个格子扩散&#xff0c;问选择那两个点使得燃烧全部的草坪花费时间最小&#xf…

K-Means聚类算法原理

来自&#xff1a;https://www.cnblogs.com/pinard/p/6164214.html K-Means算法是无监督聚类算法&#xff0c;它有很多变体。包括初始化优化K-Means&#xff0c;距离计算优化elkan K-Means算法和大样本优化Mini Batch K-Means算法。 1. K-Means原理 K-Means算法思想&#xff1a;…