此博文仅作为C++考研专业课的复习内容。

面向对象

构造函数

在对象被创建的时候将自动调用。

复制构造函数

形参是本类对象的引用。其作用是使用一个已经存在的对象,去初始化一个同类的新对象。

复制构造函数在以下三种情况会被调用。

  1. 当用类的一个对象去初始化该类的另一个对象。
  1. Point a(1,2);
  2. //两种写法都会调用复制构造函数,只是写法上不同。
  3. Point b(a);//用对象a初始化b
  4. Point c = a;////用对象a初始化b
  1. 如果函数的形参是类的对象,调用函数时,进行形参和实参结合时。
  1. void foo(Point p){
  2. cout<<p.getX()<<endl;
  3. }
  4. int main(){
  5. Point a(1,2);
  6. foo(a);
  7. return 0;
  8. }

注:值传递时调用复制构造函数,传引用时不会调用。所以传递比较大的对象时,传递引用效率会更高。

3. 如果函数的返回值是类的对象,函数执行完成返回调用者时。

  1. Point foo(){
  2. Point a(1,2);
  3. return a ;
  4. }
  5. int main(){
  6. Point b;
  7. b= foo();
  8. return 0;
  9. }

注:a离开函数foo()时,a对象会消亡,此时会调用复制构造函数创建一个无名的临时对象存在于表达式b= foo()中。

析构函数

析构函数是用来完成对象被删除前的一些清理工作,是在对象的生存期即将结束的时候被自动调用的。

析构函数的调用执行顺序与构造函数刚好相反。

类的组合

  • 当创建类的对象时,会先初始化类中的其他对象和基本数据类型的成员变量。构造函数按以下顺序调用:
  1. 调用内嵌对象的构造函数。用顺序按照内嵌对象在组合类中定义的顺序。注意,内嵌对象在构造函数的初始化列表中出现的顺序与内嵌对象构造函数的调用顺序均无关。
  2. 执行本类构造函数的函数体。
  • 析构函数的调用执行顺序与构造函数刚好相反。析构函数的函数体执行完成后,内嵌对象的析构函数一一执行。内嵌对象的析构函数调用顺序和他们在组合类中的类定义中出现的次序刚好相反。
  • 类的拷贝构造函数编写。需要为内嵌成员对象的复制构造函数传递参数。
  1. class Point{
  2. public:
  3. Point(Point& p);
  4. };
  5. class Line{
  6. private:
  7. Point p1,p2;
  8. public:
  9. Line(Point& p1,Point& p2);
  10. };
  11. Line::Line(Point& xp1,Point& xp2):p1(xp1),p2(xp2){
  12. //to-do something
  13. }

前向引用申明

  1. class B; //前向引用申明
  2. class A{
  3. public:
  4. void foo(B b);
  5. };
  6. class B{
  7. public:
  8. void bar(A a);
  9. };

当类发生循环依赖时,需要使用前向引用申明。但是即便是存在前向引用申明,但是无法直接定义类的对象。

类的静态成员

静态数据成员

static修饰。类属性是描述类的所有对象共同特征的数据项,对任何实例,他的属性值是相同的。

  1. class Point{
  2. public:
  3. Point(){
  4. count++;
  5. }
  6. void show_count(){
  7. cout<<count<<endl;
  8. }
  9. private:
  10. static int count;
  11. };
  12. int Point::count = 0;

静态数据成员单独在类外初始化,需要专门为他们分配空间。

静态函数成员

静态成员函数可以直接访问该类的静态数据和函数成员。而访问非静态成员必须通过对象名。

  1. class A{
  2. public:
  3. static void foo(A a);
  4. private:
  5. int x;
  6. };
  7. void A::foo(A a){
  8. cout<<x; //对x的引用时错误的。
  9. cout<<a.x; //正确。
  10. }

友元

友元关系提供了不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。

友元的特点

  • 友元关系无法传递。
  • 友元关系是单向的。
  • 友元关系不能被继承。

友元函数

友元函数是在类中用关键字friend修饰的非成员函数。可以是普通函数,也可以是其他类的成员函数。类的友元函数可以通过对象名访问类的私有和保护成员。

  1. class Point{
  2. Point(int x,int y);
  3. int getX();
  4. int getY();
  5. friend float dist (Point &p1,Point &p2);
  6. private:
  7. int x,y;
  8. };
  9. float dist(Point &p1,Point &p2){
  10. double x = p1.x - p2.x;
  11. double y = p1.y - p2.y;
  12. return static_cast<float>(sqrt(x * x + y * y));
  13. }
  14. int main(){
  15. Point p1(1,1),p2(4,5);
  16. cout<<dist(p1,p2);
  17. return 0;
  18. }

友元类

同友元函数一样,一个类也可以将另一个类声明为友元类。若A类为B类的友元类,则A类的所有成员都是B类的友元函数,都可以访问B类的私有和保护成员

  1. class A{
  2. public:
  3. int getX();
  4. friend class B; //B是A的友元类
  5. private:
  6. int x;
  7. };
  8. class B{
  9. public:
  10. void set(int i);
  11. private:
  12. A a;
  13. };
  14. void B::set(int i){
  15. a.x = i; //由于B是A的友元类,所以在B的成员函数中可以访问A类对象的私有成员。
  16. };

共享数据的保护

常对象

数据成员值在对象的整个生存期间内不改变。常对象必须进行初始化,而且不能被更新。

const A a(3,4);

用const修饰的类成员

  1. 常成员函数

类型说明符 函数名 (参数列表) const

eg: void foo() const;

  • 定义和申明时都要带const关键字。
  • 常对象只能调用常成员函数。
  • 无论是否通过常对象调用常成员函数,在函数调用期间,目的对象都被视为常对象,因此常成员函数不能更新目的对象的数据成员,也不能针对目的对象调用其非const修饰的函数。
  1. class A {
  2. public :
  3. void foo() const{
  4. cout<<"foo const"<<endl;
  5. this->bar();//error C2662: “A::bar”: 不能将“this”指针从“const A”转换为“A &
  6. this->x = 1;//error C3490: 由于正在通过常量对象访问“x”,因此无法对其进行修改
  7. }
  8. void bar(){
  9. cout<<"bar"<<endl;
  10. }
  11. private :
  12. int x;
  13. };
  • const可以区分函数的重载。例如申明如下函数。

void print();

void print() const;

  1. 此时常对象会调用第二个,非常对象就近调用第一个。
  1. 常数据成员

    常数据成员只能通过构造函数的初始化列表来指定具体值
  1. class A {
  2. public :
  3. A(int i):a(i){
  4. //a = i; //error
  5. }
  6. private :
  7. const int a;
  8. static const int b;
  9. //static const int b = 10; //正确 int或enum的静态常量可在类中直接指定值。
  10. };
  11. const int A::b = 10;
  1. 常引用

    所引用的对象无法更新。

    需要注意的是:
  • 非const的引用只能绑定到普通对象,但常引用可以绑定到常对象。
  • 常引用对象,通过该引用访问时,只能把对象当做常对象。(不能修改数据成员和调用非const成员函数)

C++面向对象的更多相关文章

  1. angular2系列教程(六)两种pipe:函数式编程与面向对象编程

    今天,我们要讲的是angualr2的pipe这个知识点. 例子

  2. 一起学 Java(二)面向对象

    一.方法函数 函数也称为方法,就是定义在类中的具有特定功能的一段独立代码.用于定义功能,提高代码的复用性. 函数的特点1> 定义函数可以将功能代码进行封装,便于对该功能进行复用:2> 函数 ...

  3. js面向对象学习 - 对象概念及创建对象

    原文地址:js面向对象学习笔记 一.对象概念 对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”.也就是一组名值对的无序集合. 对象的特性(不可直接访问),也就是属性包含两种,数 ...

  4. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  5. .NET 基础 一步步 一幕幕[面向对象之对象和类]

    对象和类 本篇正式进入面向对象的知识点简述: 何为对象,佛曰:一花一世界,一木一浮生,一草一天堂,一叶一如来,一砂一极乐,一方一净土,一笑一尘缘,一念一清静.可见"万物皆对象". ...

  6. 简单分析JavaScript中的面向对象

    初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...

  7. Java程序员应该了解的10个面向对象设计原则

    面向对象设计原则: 是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton.Decorat ...

  8. JavaScript学习笔记(三)——this、原型、javascript面向对象

    一.this 在JavaScript中this表示:谁调用它,this就是谁. JavaScript是由对象组成的,一切皆为对象,万物皆为对象.this是一个动态的对象,根据调用的对象不同而发生变化, ...

  9. 带你一分钟理解闭包--js面向对象编程

    上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...

  10. .NET基础拾遗(2)面向对象的实现和异常的处理基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

随机推荐

  1. Apache error: 403 Forbidden You don't have permission to access

    CentOS 6 solution: chcon -t httpd_sys_content_t -R /directory refer to: https://www.centos.org/forum ...

  2. 【hihoCoder】1036 Trie图

    题目:http://hihocoder.com/problemset/problem/1036 给一个词典dict,词典中包含了一些单词words.要求判断给定的一个文本串text中是否包含这个字典中 ...

  3. ant的安装及项目的发布

    1.安装ant1) 直接解压apache-ant-1.9.7-bin 2) 在环境变量中配置,ant_home的环境变量在 3) 在命令提示符中测试是否安装成功. 2 项目首次打包1) 写好打包的配置 ...

  4. 浏览器调试js技巧总结

    一.控制台console的运用 console.log(aa|'aa'): 将需要打印的东西输出的控制台,在调试的时候很有用,可以知道aa是否是自己想要的数据类型,或者可以知道程序是否执行到了这一步, ...

  5. awk使用shell变量

    awk使用shell变量  (可以计算浮点数) 其实在awk里,是不能直接使用shell变量的 方法是:awk -v 选项让awk 里使用shell变量 TIME=60 awk -v time=&qu ...

  6. C# winform treeView checkbox全选反选

    private void treeView2_AfterCheck(object sender, TreeViewEventArgs e)        {            if (e.Acti ...

  7. 广州PostgreSQL用户会技术交流会小记 2015-9-19

    广州PostgreSQL用户会技术交流会小记 2015-9-19 今天去了广州PostgreSQL用户会组织的技术交流会 分别有两个session 第一个讲师介绍了他公司使用PostgreSQL-X2 ...

  8. 多种坐标系之间的转换 Proj.NET和DotSpatial

    Proj.NET ( http://projnet.codeplex.com/)是一个.NET下开源的空间参照和投影引擎,遵循OGC相关标准.负责人(Coordinators )是D_Guidi 和S ...

  9. jQuery 2.0.3 源码分析 Deferred(最细的实现剖析,带图)

    Deferred的概念请看第一篇 http://www.cnblogs.com/aaronjs/p/3348569.html ******************构建Deferred对象时候的流程图* ...

  10. nodejs事件轮询详述

    目录 概述 nodejs特点 事件轮询 关于异步方法 概述 关于nodejs的介绍网上资料非常多,最近由于在整理一些函数式编程的资料时,多次遇到nodejs有关的内容.所以就打算专门写一篇文章总结一下 ...