前言:本笔记所对应的课程为中国大学mooc中北京大学的程序设计与算法(三)C++面向对象程序设计,主要供自己复习使用,且本笔记建立在会使用c和java的基础上,只针对与c和java的不同来写

类和对象提高

this指针

作用就是指向成员函数所做用的对象,注意它是一个指针。

class Complex{
public:
double real, imag;
Complex AddOne(){
this->real++;
return * this;
}
};

静态成员函数之中没有this指针,因为静态成员函数不具体作用于某个对象。

对象的成员函数在被解释时会多增加一个参数,即指向自己这个对象的this指针。因此存在下面这样一个特殊的用法:

class A{
public:
int i = 0; void hello1(){
cout << "hello" << endl;
} void hello2(){
cout << i << "hello" << endl;
}
}; int main(){
A * p = NULL;
p->hello1(); //正确,输出hello
p->hello2(); //错误
}

原因:

void hello1(){ cout << "hello" << endl; }被解释为void hello1(A * this){ cout << "hello" << endl; }

void hello2(){ cout << i << "hello" << endl;}被解释为void hello2(A * this){ cout << this->i << "hello" << endl;}

p->hello1();被解释为hello1(p)

p->hello2();被解释为hello2(p)

静态成员变量与函数

静态成员变量的用法与java相同。

需要注意的是必须在定义类的文件中,在所有的类和函数之外,对静态变量进行说明(可选择初始化,也可不选),具体方法如下:

class A{
public:
static int total;
}; int A::total = 0; void main(){ }

静态成员函数的访问方法:

  1. 类名::成员名 Circle::Print();
  2. 对象名.成员名 Circle c; c.Print();
  3. 指针->成员名 Circle * p = &c; p->Print();
  4. 引用.成员名 Circle & r = c; r.Print();

同java一样,在静态成员函数中不可以访问非静态成员变量,也不可以调用非静态成员函数。

注意复制构造函数和析构函数的隐式调用可能会对静态成员变量的值产生影响。

成员对象和封闭类

成员对象:某一个类中的成员变量是另一个类的对象。

封闭类:具有成员变量的类。

任何生成封闭类对象的语句,都要使编译器明白,对象中的成员对象,是如何初始化的。

如何做到:通过封闭类的构造函数的初始化列表为成员对象初始化。

封闭类构造函数和析构函数的执行顺序:

  1. 封闭类对象生成时,先执行成员对象的构造函数,再执行封闭类的构造函数。
  2. 成员对象的构造函数的执行顺序与其在类中的说明次序一致,与在构造函数初始化列表中的顺序无关。
  3. 封闭类对象消亡时,先执行封闭类的析构函数,再执行成员对象的析构函数。先构造的后析构

常量对象、常量成员函数

常量对象与常量成员函数:不可以修改成员变量的值(除静态成员变量),也不可以调用同类的非常量成员函数(除静态成员函数)。定义方法如下:

class Circle{
public:
int value;
void GetValue() const; //定义常量成员函数
void func();
}; void Circle::GetValue() const{
value = 0; //wrong
func(); //wrong
} int main(){
const Circle c; //定义常量对象
c.value = 0; //wrong
c.func(); //wrong
c.GetValue(); //ok return 0;
}

常量函数与其同名的函数是重载的关系。

友元

友元函数:一个类的友元函数不是这个类的成员函数,但是可以访问该类的私有成员。

友元类:如果A是B的友元类,那么A的所有成员函数都可以访问B的私有成员。

友元关系不可继承,不可传递。

使用方法如下:

class Car;
class Driver{
public:
void ModifyCar(Car * pcar);
}; class Car{
private:
int price;
friend int MostExpensiveCar(Car cars[], int total); //在这里声明
friend void Driver::ModifyCar(Car * pcar);
friend Type; //在这里声明
}; class Type{ }; void Driver::ModifyCar(Car * pcar){ } int MostExpensiveCar(Car cars[], int total){ } int main(){
return 0;
}

最新文章

  1. nginx实现请求转发
  2. Windows自带压缩解压工具
  3. log4net 按时间输出日志
  4. 【POJ】1062 昂贵的聘礼(spfa)
  5. 怎么用EDIUS实现跟踪马赛克效果
  6. 【jdbcTemplate】使用jdbcTemplate查询的三种回调
  7. 配置使VirtualBox下的linux可以宿主机互访并上网
  8. C/C++易错点
  9. webstorm 如何配置git
  10. SharePoint 2013 实战碎嘴(ECMAScript客户端对象模型): 提示某个列表不存在
  11. Centos6.4 NFS的安装与配置
  12. 【机器学习】RNN学习
  13. 新概念英语(1-43)Hurry up!
  14. 【转】GB2312、GBK和UTF-8三种编码的简要说明
  15. Mac appStore下载软件报500错误的解决方法
  16. LVS管理工具ipvsadm详解与LVS-NAT模式演示
  17. 01-python基础知识
  18. python学习读取配置文件
  19. 配置redis, make的时候: zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录
  20. GO/GOLANG程序员笔记大全

热门文章

  1. VS 运行库MT、MD的区别
  2. 一个简单易上手的短信服务Spring Boot Starter
  3. node 初级概念总结
  4. GitHub 更新fork的代码
  5. 【CTS2019】珍珠【生成函数,二项式反演】
  6. JavaWeb_(SpringMVC框架)SpringMVC入门
  7. Java学习日记——基础篇(一)常识
  8. oracle行转列和列转行(pivot 和 unpivot 函数,wm_concat函数 )
  9. nodejs 服务器模拟异常状态码429,以及前端vue axios捕获状态码
  10. Rect和RectF函数