一、static成员变量和static成员函数

1.普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享

2.普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。

3.因此静态成员不需要通过对象就能访问

4.静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。静态成员函数本质上是全局函数。

5.设置静态成员这种机制的目的是将和某些类紧密相关的全局变量和函数写到类里面,看上去像一个整体,易于维护和理解。

注意:

  1.必须在定义类的文件中对静态成员变量进行一次说明或者初始化,否则编译能通过,但链接不能通过。

  2.在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。

二、this指针和静态成员函数

1.静态成员函数中不能使用this指针

  因为静态成员函数并不具体作用于某个对象。因此,静态成员函数的真实的参数的个数,就是程序中写出的参数个数。

三、关于const的全部用法

1.常量对象

  如果不希望某个对象的值被改变,则定义该对象的时候可以在前面加const关键字。

2.常量成员函数

  在类的成员函数说明后面可以加const关键字,则该成员函数成为常量成员函数。

  常量成员函数执行期间不应修改其所作用的对象。因此在常量成员函数中不能修改成员变量的值(静态成员变量除外),也不能调用同类的非常量成员函数(静态成员函数除外)。

注意:

  两个成员函数,名字和参数表都一样,但是一个是const,一个不是,算重载。

3.常引用

  引用前面可以加const关键字,成为常引用。不能通过常引用,修改其引用的变量。

四、非引用的函数返回值不可以作为左值使用。

五、public继承的赋值兼容规则

1.派生类的对象可以赋值给基类对象。

2.派生类的对象可以初始化基类的引用。

3.派生类的对象的地址可以赋值给基类指针。

六、C++如下运算符不能重载:
“.”    ".*"      "::"     "?:"     sizeof

七、函数模板调用顺序:

1.先找参数完全匹配的普通函数(非自由模板实例化而得的函数)

2.再找参数完全匹配的的模板函数

3.再找实参经过自动类型转换后能够匹配的普通函数

4.上面的都找不到,则报错

备注:

赋值兼容规则引起函数模板中类型参数的二义性

 template <class T>

 T func(T a, T b) {

   cout << "a = " << a << endl;

   return a;

 }

 func(, );   // ok: replace T with int

 func(5.8, 8.4); // ok: replace T with double

 func(, 8.4);  // error: replace T with int or double ??

针对上面问题的解决方案如下:

可以在函数模板中使用多个类型参数,可以避免二义性

 template <class T1, class T2>

 T1 func(T1 a, T2 b) {

   cout << "a = " << a << endl;

   return a;

 }

 func(, );   // ok: replace T1 and T2 with int

 func(5.8, 8.4); // ok: replace T1 and T2 with double

 func(, 8.4);  // ok: replace T1 with int, T2 with double

八、构造函数

1.复制构造函数(copy constructor)

  1)复制构造函数只有一个参数,即对同类对象的引用。

  2)形如 X::X( X & )或者X::X( const X & ),二选一,后者能以常量对象作为参数

  3)如果没有定义复制构造函数,那么编译器生成默认复制构造函数。默认的复制构造函数完成复制功能。

  备注:如果定义了自己的复制构造函数,则默认的复制构造函数不再存在。

      不允许有形如X::X ( X )的构造函数

class CSample{
CSample( CSample cs) {
} // 错,不允许这样的构造函数
};

2.复制(拷贝)构造函数起作用的三种情况

  1) 当用一个对象去初始化同类的另一个对象时。

 Complex c2(c1);
Complex c2 = c1; // 初始化语句,非赋值语句

  2)如果某函数有一个参数是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用。

 class A {
public:
A(){};
A( A &a) {
cout << "Copy constructor called" << endl;
}
}; void Func(A a1) { } int main(void)
{
A a2;
Func(a2);
return ;
}

程序输出结果:

Copy constructor called

  3)如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数将被调用:

 class A {
public:
int v;
A(int n) { v = n; }
A( const A &a ) {
v = a.v;
cout << "Copy constructor called" << endl;
}
}; A Func() {
A b();
return b;
} int main(void) {
cout << Func().v << endl;
return ;
} // 输出结果:
Copy constructor called

3.类型转换构造函数

类型转换构造函数只有一个参数,它不同于复制构造函数。

编译系统会自动调用转换构造函数,建立一个临时对象/临时变量

 class Complex{
public:
double real, imag; Complex(int i) { // 类型转换构造函数
cout << "IntConstructor called" << endl;
real = i;
imag = ;
}
Complex(double r, double i) {
real = r;
imag = i;
}
}; int main(void) { Complex c1(, );
Complex c2 = ;
c1 = ;
cout << c1.real << "," << c1.imag << endl;
return ;
} // 输出:
IntConstructor called
IntConstructor called
,

Complex(int)这个构造函数就是类型转换构造函数。可以看出,该构造函数一共被调用了两次。第一次来自于对c2的初始化,第二次来自于第20行的赋值语句。

这条赋值语句的等号两边类型是不匹配的,之所以不会报错,就是因为Complex(int)这个类型转换构造函数能够接受一个整型参数。因此,编译器在处理这条赋值语句的时候,

会在等号右边自动生成一个临时的Complex对象,该临时对象以9为实参,用Complex(int)这个构造函数初始化,然后再将这个临时对象的值赋给c1,也可以说是9被自动转换成一个

Complex对象然后再赋值给c1。要注意,第19行是初始化语句,而不是赋值语句。所以,不会将12转换成一个临时对象,而是直接以12作为参数调用Complex(int)构造函数来初始化c2。

九、私有成员的访问权限:

类的成员函数内部,可以访问:

  1)当前对象的全部属性,函数

  2)同类其他对象的全部属性,函数

类的成员函数以外的地方:

  1)只能够访问该类对象的公有成员

十、静态成员变量static

普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享。sizeof运算符不会计算静态成员变量。

普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。因此,静态成员不需要通过对象就能访问。

静态成员的访问:

1) 类名::成员名

  CRectangle::PrintTotal();

2) 对象名.成员名

  CRectangle r; r.PrintTotal();

3) 指针->成员名

  CRectangle *p = &r; p->PrintTotal();

4) 引用.成员名

  CRectangle &ref = r;  int n = ref.nTotalNumber;

静态成员变量,本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。

静态成员函数本质上是全局函数。

设置静态成员这种机制的目的是将和某些类紧密相关的全局变量和函数写到类里面,看上去像一个整体,易于维护和理解。

 class CRectangle
{
private:
int w, h;
static int nTotalArea;
static int nTotalNumber;
public:
CRectangle(int w_,int h_);
~CRectangle();
static void PrintTotal();
}; CRectangle::CRectangle(int w_,int h_) {
w = w_;
h = h_;
nTotalNumber ++;
nTotalArea += w * h;
} CRectangle::~CRectangle() {
nTotalNumber --;
nTotalArea -= w * h;
} void CRectangle::PrintTotal() {
cout << nTotalNumber << "," << nTotalArea << endl;
} int CRectangle::nTotalNumber = ;
int CRectangle::nTotalArea = ;
// 必须在定义类的文件中对静态成员变量进行一次说明
//或初始化。否则编译能通过,链接不能通过。
int main()
{
CRectangle r1(,), r2(,);
//cout << CRectangle::nTotalNumber; // Wrong , 私有
CRectangle::PrintTotal();
r1.PrintTotal();
return ;
} // 输出:
,
,

注意事项:

在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。

 void CRectangle::PrintTotal()
{
cout << w << "," << nTotalNumber << "," << nTotalArea << endl; //wrong
} CRetangle::PrintTotal(); //解释不通,w 到底是属于那个对象的?

在CRectangle类的写法中,有何缺陷?

 CRectangle::CRectangle(int w_,int h_) {
w = w_;
h = h_;
nTotalNumber ++;
nTotalArea += w * h;
} CRectangle::~CRectangle() {
nTotalNumber --;
nTotalArea -= w * h;
} void CRectangle::PrintTotal() {
cout << nTotalNumber << "," << nTotalArea << endl;
}

在使用CRectangle类时,有时会调用复制构造函数 生成临时的隐藏的CRectangle对象

  调用一个以CRectangle类对象作为参数的函数时,

  调用一个以CRectangle类对象作为返回值的函数时

临时对象在消亡时会调用析构函数,减少nTotalNumber 和 nTotalArea的值,可是这些临时对象在生成时却没有增加 nTotalNumber 和 nTotalArea的值。

解决办法:为CRectangle类写一个复制构造函数。

 CRectangle :: CRectangle(CRectangle & r ) {
w = r.w;
h = r.h;
nTotalNumber ++;
nTotalArea += w * h;
}

参考:

www.coursera.org上的pku公开课C++程序设计

《新标准C++程序设计教程》,郭炜

C++基本语法的更多相关文章

  1. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  2. Swift与C#的基础语法比较

    背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...

  3. 探索C#之6.0语法糖剖析

    阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...

  4. [C#] 回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性

    回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 ...

  5. Velocity初探小结--velocity使用语法详解

    做java开发的朋友一般对JSP是比较熟悉的,大部分人第一次学习开发View层都是使用JSP来进行页面渲染的,我们都知道JSP是可以嵌入java代码的,在远古时代,java程序员甚至在一个jsp页面上 ...

  6. node.js学习(二)--Node.js控制台(REPL)&&Node.js的基础和语法

    1.1.2 Node.js控制台(REPL) Node.js也有自己的虚拟的运行环境:REPL. 我们可以使用它来执行任何的Node.js或者javascript代码.还可以引入模块和使用文件系统. ...

  7. C#语法糖大汇总

    首先需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕 ...

  8. 值得注意的ibatis动态sql语法格式

    一.Ibatis常用动态sql语法,简单粗暴用一例子 <select id="iBatisSelectList" parameterClass="java.util ...

  9. Flex 布局教程:语法篇

    作者: 阮一峰 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便 ...

  10. postgresql 基本语法

    postgresql数据库创建/修改/删除等写入类代码语法总结: 1,创建库 2,创建/删除表 2.1 创建表 create table myTableName 2.2 如果表不存在则创建表 crea ...

随机推荐

  1. 通过CAGradientLayer制作渐变色效果(转)

    转载自:http://blog.it985.com/7986.html 看了极客学院的视频之后写的一篇博客,觉得不错,还是作为笔记使用. 简单介绍一下CAGradientLayer吧. Gradien ...

  2. Win10 PC一周年更新正式版14393.447 32位/64位更新补丁KB3200970下载 Flash补丁Kb3202790下载

    微软在今天凌晨推送了Win10 PC一周年更新正式版14393.447,本次更新补丁代号为KB3200970,面向Win10一周年更新正式版的PC用户. 更新日志 • 提升了多媒体音频.远程桌面以及I ...

  3. Android实现透明式状态栏

    Android实现透明式状态栏 1. 修改style样式 2.  创建values-v19文件夹 3.  在这个文件夹下创建style.xml 4.  对activity_main.xml进行修改 移 ...

  4. jQuery Colorpicker Spectrum api 中文 文档 属性 事件 方法

    jQuery Colorpicker Spectrum 所需的CSS和JavaScript文件: <script src='spectrum.js'></script> < ...

  5. 深入浅出HTTP请求(转自http://www.cnblogs.com/yin-jingyu/archive/2011/08/01/2123548.html)

    HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则.计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器(Web服务 器)请 ...

  6. JS控制flash的方法

    JS控制flash的一些方法:Play() ---------------------------------------- 播放动画 StopPlay()---------------------- ...

  7. 使用mosh取代ssh提高n2n网络连接稳定性

    上文实现了远程n2n访问树莓派,但是ssh协议在网络状况不好的时候命令会卡住.这里发现了一个mosh协议,可以增强稳定性,使用后效果明显. 背景:使用n2n之后,在比较差的网络环境下,经常会被time ...

  8. thinkphp 后台权限列表

    核心代码: // 检测用户权限权限 public function admin_priv($action){ $action_list = session('user.action_list'); i ...

  9. CSS line-height与vertical-align:baseline

    一.当line-height与vertical-align相遇,会发生很多匪夷所思的现象 首先,请看如下代码: <!DOCTYPE html> <html> <head& ...

  10. AP(affinity propagation)研究

    待补充…… AP算法,即Affinity propagation,是Brendan J. Frey* 和Delbert Dueck于2007年在science上提出的一种算法(文章链接,维基百科) 现 ...