[C++]变量存储类别,指针和引用,类与对象,继承与派生的一些摘要
C++中共有四种存储类别标识符:auto/static/register/extern
1.auto
函数或分程序内定义的变量(包括形参)可以定义为auto(自动变量)。如果不指定存储类别,则隐式定义为auto。
例如,函数类有如下定义:
auto int x , y ;
等价于:
int x , y ;
2.static
除了形参,可以将局部变量和全局变量定义为静态变量。用static标识符。
static int a;//a是全局静态变量
f()
{static int b = 1;}//b是局部静态变量
与auto不同,static变量的生存期是程序开始运行到运行结束(auto变量生存期是函数调用结束)。
若定义静态变量时没有对其赋初值,系统自动赋初值0;若赋初值,则仅在编译时赋初值一次,程序运行后不再给变量赋初值。当上一次调用局部静态变量所在的函数时,该变量的值继续有效(为上次函数调用结束时保留的值)。
3.extern
在函数外定义的变量如果没有用static声明,则是extern外部变量。外部变量只能隐式定义为extern,不能显示定义。
对外部变量声明时,系统不分配存储空间。
#include <iostream> using namespace std;
int x = , y = ;//定义外部变量
void f1()
{
extern char c1 , c2 ;//声明外部变量
cin>>c1>>c2;
}
char c1 , c2 ;//定义外部变量 int main()
{
int m , n ;
f1();
cout <<c1<<"+"<<c2<<"="<<x+y<< endl;
return ;
}
结果是这样:

注意,如果把extern去掉了,再输入xy,回车,会出现:

因为c1,c2的作用域只在f1函数里面。如果不用extern,想达到第一幅的效果,只要把
char c1 , c2 ;//定义外部变量
这句拿到f1()前面就行了。
4.register
寄存器变量的值保存在CPU的寄存器中,读写速度更快。随着计算机硬件性能提高,现在寄存器变量使用得比较少了。
------------------------------------------------
指针和引用:
指针 = *指针变量
&取地址运算符,返回其指向的变量或数组元素的地址。
&取地址
*取目标变量
这两个运算符互为逆运算,如图(Page129,《C++程序设计》,姚琳,人民邮电出版社):

赋值运算:

注意,
可以把一个已经初始化的指针值非给另一指针,例如:
float x, *p = &x, *q = p;
可以把*理解成跟float连在一起。
这样,q和p有相同的地址,指向x。
引用(<数据类型名> &引用名=变量名;):

补充:改错题:
void test(char * OldName){
char[] NewName;
int len=;
for(;OldName[len] != '\0';len++){
NewName[len] = OldName[len];
}
return;
}
两个错误,
1.C语言中的数组定义跟Java还是有区别的,不能像上面那样定义,而要写成char NewName[30];而且NewName后面不能有空格;
2.OldName的长度需要设定一下,不然超过30之后,NewName没有那么多元素,出现溢出错误。
Mr.Yin:对于其中指针的理解,其实char NewName[30]; 比如NewName[0]就是下图的0x01元素,那么NewName就是0x00ff,也就是一个地址。
| 0x01 |
0x00ff
同理,有:
p[i] = *(p+i)
-----------------2016年1月26日 带成瑞------------------------------------------------------
&p[i] = p+i
类的定义:
跟Java不同,C++中类定义结束之后,要加分号。
class Student
{
public :
void printStudent(); private:
int id;
char* name ;
char sex;
};
其中,成员函数printStudent()以函数声明的形式出现。成员函数的具体实现可以放在类定义的外部:
void Student::printStudent()
{
cout<<"id:"<<id<<","<<"name:"<<name<<","<<"sex:"<<sex<<endl;
}
成员函数的定义和一般函数的定义区别在于「类名」和「::」构成作用域,表示出该成员函数属于的类。
一般来说,类的成员函数都放在类外进行。
一个基本原则:尽量将成员数据和成员函数设计成私有访问控制属性,体现类的「封装性」。
类的访问属性private和public的访问规则:

静态成员和友元:
静态成员数据是一个类的所有对象共享的数据成员,静态成员数据与一般数据的区别在于:对于静态成员数据,该类的每个对象都共享唯一的数据,即它只存在一份拷贝,而对于一般成员数据,该类的每个对象都独立简历自己的一个副本,以保存各自特定的值。因此,静态成员数据属于类级别的成员,而一般成员数据属于对象级别的成员。
初始化静态成员数据必须在类外进行。
比如:
class Student
{
public :
void printStudent(); private:
int id;
char* name ;
char sex;
};
其中,成员函数printStudent()以函数声明的形式出现。成员函数的具体实现可以放在类定义的外部:
void Student::printStudent()
{
cout<<"id:"<<id<<","<<"name:"<<name<<","<<"sex:"<<sex<<endl;
}
成员函数的定义和一般函数的定义区别在于「类名」和「::」构成作用域,表示出该成员函数属于的类。
一般来说,类的成员函数的定义都放在类外进行。
一个基本原则:尽量将成员数据和成员函数设计成私有访问控制属性,体现类的「封装性」。
class Student
{
public:
... private:
static int count;//静态成员数据的定义
}
int Student::count=;//静态成员数据的初始化
静态成员函数是一个类所有对象共享的成员函数。静态成员函数也成为类成员函数(因为静态成员函数和静态成员数据属于类层次,而一般成员函数和一般成员数据属于对象层次。)
没有对象生成时,静态成员函数中是不能访问一般成员函数和一般成员数据的。
静态成员函数放在类内声明,类外初始化(事实上一般来说,成员函数的初始化都放在类外进行)。
友元:
静态成员数据提供了在一个类的所有对象之间共享数据的机制。
而友元则是不同类的成员函数之间、类的成员函数和一般函数之间进行数据共享的机制,破坏了封装性和数据隐藏性。不提倡使用。友元可以定义在函数级别或是类级别。
常对象(类名 const 对象名;):
对于基本数据类型的变量,可以定义符号常量,其值在程序运行过程中保持不变。
对于「类」这种自定义数据类型,同样可以定义一种对象,使得数据成员保持不变,也就是常对象。
常成员:
(1)常成员数据:可以通过定义常成员数据使得部分成员数据的值保持不变。
const 数据类型 变量名;
一般符号常量的定义和初始化是在同一语句中实现的,而常成员数据的初始化通常是分开进行的,在类的初始化列表处进行。
class Student
{
public:
Student(int pId , Char*pName , int pAge);
private:
const int id;
char* name;
int age;
};
Student::Student(int pId, char* pName, int pAge):id(pId)//这个构造函数后面的id(pId也可以理解为id变量的构造函数,在这里初始化。----Mr.Yin)
(2)常成员函数:
数据类型 函数名(形参列表) const;
1.常成员函数不能调用一般成员函数。
2.const可作为重载条件。如void printAdmin()和void printAdmin() const构成一对重载函数。
3.常对象只能定义常成员函数,不能访问一般函数。
继承与派生:
定义派生类的一般方式:
class 派生类名:继承方式 基类1,继承方式 基类2,..继承方式 基类n
{
//派生类新增的成员声明
};
例如:设已有基类base1和base2,定义派生类deriver:
class deriver: public base1 , private base2
{
private:
int m_derdate;
public:
void derfun();
}
以上定义的派生类deriver以共有方式继承基类base1,以私有方式继承基类base2,并且新增加了两个成员。
派生类自己增加的成员,完成两个需求:修改基类成员和描述新的特征和方法。
派生类修改基类的成员,通过在派生类中声明一个与基类成员同名的新成员来实现(同Java中的override)。
继承的访问控制(拍书狂魔):
主要看下划线和最下面的表格:
看public和protected:
区别在第三点:派生类以外的其他函数不可以通过派生类的对象访问从基类继承的公有成员。我理解的意思也就是,派生类不能作为一个媒介,让其他函数通过这个派生类来调用基类中的成员。

多重继承的二义性和虚基类

基类base的成员,先被继承到派生类Fderiver1,Fderiver2,然后又要被继承到派生类Sderiver,则爱生类Sderiver中有base的成员的两份拷贝。出现ambiguous错误,也就是二义性。
为解决这个问题,可以将共同基类设置成虚基类,这样在创建派生类对象时,虚基类的构造函数只调用一次,虚基类的成员在第三层派生对象中只有一份拷贝。
上例中,首先将base声明为虚基类:
class Fderiver1:virtual public base
{
//..原来的代码
};
class Fderiver2:virtual public base
{
//..原来的代码
};
其次,对第二级派生类Sderiver的构造函数作修改:
Sderiver(int attrib,int data):base(data),Fderiver1(value,data),Fderiver2(number,data)
{
//...
}
(按:上面的构造函数后面的冒号:base(data)的用法是初始化,初始化跟赋值不同,初始化在分配内存的时候直接赋值,是一步操作;赋值是两步操作。)
编译系统只执行其中的base(data)调用对虚基类构造函数的调用,而忽略通过Fderiver1(value,data)和Fderiver2(number,data)对虚基类构造函数的调用。
--------------------------------------------
多态性与虚函数
多态性是指相同的函数名或者运算符在不同场合下使用,能表现出不同的行为或特征。
标准模板库
标准模板库(Standard Template Library,STL)主要内容包括容器、算法和迭代器。
容器有7种,分别是:向量,栈,列表,双端队列,集合,多重集合,映射。
向量:大小可变,可以像数组一样直接访问(at得到编号位置的数据),也可以像链表一样顺序访问。
一维向量的数据存取:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int i = ;
vector<int> v ;//定义元素为整形的一维变量
for(i = ; i < ; i++)
{
v.push_back(i);//push_back在容器的最后添加一个数据
}
for(i = ; i<v.size() ; i ++)
{
cout<<v[i]<<" ";
}
cout<<endl;
return ;
}
程序运行结果:
0 1 2 3 4 5 6 7 8 9
其中,上面的
for(i = ; i<v.size() ; i ++)
{
cout<<v[i]<<" ";
}
用迭代器实现:
vector<int>::iterator iter;
for(iter = v.begin; iter!=v.end(); iter++)//begin获取容器头指针,end获取尾指针+1
{
cout<<*iter<<" ";
}
[C++]变量存储类别,指针和引用,类与对象,继承与派生的一些摘要的更多相关文章
- C++变量存储类别和内存四区
变量存储类别 变量声明/定义的一般形式: 存储类别 数据类型 变量名 存储类别指的是数据在内存中存储的方法.存储方法分为静态存储和动态存储两大类.标准C语言为变量.常量和函数定义了4种存储类型:ext ...
- C语言中存储类别又分为四类:自动(auto)、静态(static)、寄存器的(register)和外部的(extern)。
除法运算中注意: 如果相除的两个数都是整数的话,则结果也为整数,小数部分省略,如8/3 = 2:而两数中有一个为小数,结果则为小数,如:9.0/2 = 4.500000. 取余运算中注意: 该运算只适 ...
- c++中变量、变量名、变量地址、指针、引用等含义
首先了解内存,内存就是一排房间,编号从0开始,0,1,2,3,4,5...... 房间里面一定要住人,新人住进去了,原来的人就走了:不管你住不住,里面都有人. 编号就是地址.里面的人就是内容,为了我们 ...
- 类与对象 && 继承
以下是本人的对类与对象.继承的一些理解,如有错误之处万望谅解,如有朋友愿意指正,十分乐意,万分感谢! 类与对象 类与对象是学习编程的基础(大概吧),那么何为类?何为对象呢? 一.简 ...
- python3 之 面向对象(类)、继承、派生和多态
类提供了一种 组合数据和功能 的方法.创建一个新类意味着:创建一个新 类型 的对象,从而允许创建一个该类型的新 实例. 每个类的实例可以拥有: 保存自己状态的属性. 一个类的实例也可以有改变自己状态 ...
- Java自学-类和对象 继承
什么是 Java的 继承 ? 在LOL中,武器是物品的一种,也是有名称和价格的 所以在设计类的时候,可以让武器继承物品,从而继承名称和价格属性 步骤 1 : 物品类Item 物品类Item 有属性 n ...
- (转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考
昨天去面试一家公司,面试题中有一个题,自己没弄清楚,先记录如下: class D { public: void printA() { cout<<"printA"< ...
- C++对象的复制——具有指针成员的类的对象的复制
//smartvessel@gmail.com class Table{ Name * p; size_t sz; publish: Table(size_t s = 15){p = new Name ...
- C++变量作用域、生存期、存储类别
写C.C++代码的小伙伴一定在头疼变量的作用域.生存期.存储类别问题.什么静态.外部.寄存器.局部.全局搞得一头雾水.今天咱们就来梳理一下他们的变态关系(什么不得了的事情???) 1.变量的作用域 说 ...
随机推荐
- maven运行update命令时报org/apache/maven/shared/filtering/MavenFilteringException错误
在eclipse中对准项目运行maven->update project命令时报错:org/apache/maven/shared/filtering/MavenFiltering ...
- android wifi相关模块 命令列表 汇总
static final int BASE =Protocol.BASE_WIFI; 131072 static final intCMD_START_SUPPLICANT = BASE +11; ...
- hdu杭电1856 More is better【并查集】
Problem Description Mr Wang wants some boys to help him with a project. Because the project is rathe ...
- visual c++ 2013进行MySQL编程(ODBC) -- (一) 套装安装
最近写了有些技术类文章了,只因为最近研究多了些东西,有一些项目用到了,所以自己记录一下,怕自己忘记,如果有哪位同学有自己的见解,可以邮件或者回复,技术类的探讨,不管对否,都是欢迎的. 操作之前,必须安 ...
- hdu 1548
A strange lift Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- S3C2440 IIS操作 uda134x录放音
IIS(Inter-IC Sound)由飞利浦公司开发.是一种经常使用的音频设备接口,主要用于CD.MD.MP3等设备. s3c2440一共同拥有5个引脚用于IIS:IISDO.IISDI.IISSC ...
- 超越MySQL:三个流行MySQL分支的对比(转)
导读:尽管MySQL是最受欢迎的程序之一,但是许多开发人员认为有必要将其拆分成其他项目,并且每个分支项目都有自己的专长.该 需求以及Oracle对核心产品增长缓慢的担忧,导致出现了许多开发人员感兴趣的 ...
- Cocos2d-X中提高性能的方法
1)内存使用效率: 使用大纹理 场景切换时,要尽量使用replaceScene 2)用好缓存: CCTextureCache(纹理缓存) CCSpriteFrameCache(精灵帧缓存) CC ...
- RuntimeWarning: Parent module 'test_project.test_case' not found while handling absolute
1.Pycharm2016.3.2,导入unittest框架后,运行脚本总是warming,但不影响脚本具体执行 2.通过网上查询,将"C:\Program Files\JetBrains\ ...
- 【LeetCode with Python】 Sort List
博客域名:http://www.xnerv.wang 原题页面:https://oj.leetcode.com/problems/sort-list/ 题目类型: 难度评价:★ 本文地址:http:/ ...