android 源码阅读的C++语法准备4 面向对象

1. 类和对象

class Box
{
   public://private 或 protected
      double length;   // 盒子的长度
      double breadth;  // 盒子的宽度
      double height;   // 盒子的高度
      double getVolume(void)  //类的成员函数
      {
         return length * breadth * height;
      }
      Box();//构造函数
      Box(double length);//带参数的构造函数
      ~Box();//析构函数
      Box(const Box &obj);// 拷贝构造函数
      friend void printWidth( Box box ); //友元函数
   private:
      double *ptr;
};
Box::~Box(void)
{
    cout << "Object is being deleted" << endl;
}
Box::Box(const Box &obj)
{
    cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
    ptr = new double;
    *ptr = *obj.ptr; // 拷贝值
}
 
Box Box1;// 声明 Box1,类型为 Box
Box Box2;// 声明 Box2,类型为 Box

// box 1 详述
Box1.height = 5.0; 
Box1.length = 6.0; 
Box1.breadth = 7.0;

成员函数

除了可以在 class 内部定义成员函数,也可以在类的外部使用范围解析运算符 :: 定义该函数,如下:

double Box::getVolume(void)
{
    return length * breadth * height;
}

:: 叫作用域区分符,指明一个函数属于哪个类或一个数据属于哪个类。

:: 可以不跟类名,表示全局数据或全局函数(即非成员函数)。

C++ 类访问修饰符

public、private、protected,成员和类的默认访问修饰符是 private。保护(protected)成员变量或函数与私有成员十分相似,但有一点不同,保护成员在派生类(即子类)中是可访问的,而 priavte 是不可以的。

类继承时使用修饰符

有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。

  • 1.public 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected
  • 2.protected 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:protected, protected,有继承下来但说父类的成员不能被子类对象调用了
  • 3.private 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:private, private,有继承下来但父类的成员不能被子类对象调用了

但无论哪种继承方式,上面两点都没有改变:

  • 1.private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;
  • 2.protected 成员可以被派生类访问。
class B : public A{
  
}

类的构造函数

会在每次创建类的新对象时执行

注意一种带初始化列表的构造函数

C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
  ....
}
//eg:
Box::Box( double len): length(len)
{
    cout << "Object is being created, length = " << len << endl;
}

//相当于
Box::Box( double len)
{
    cout << "Object is being created, length = " << len << endl;
    length = len;
}

类的析构函数

在每次删除所创建的对象时执行

析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

C++ 拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。如果在类中没有定义拷贝构造函数,编译器会自行定义一个。拷贝构造函数通常用于:

  • 通过使用另一个同类型的对象来初始化新创建的对象。
  • 复制对象把它作为参数传递给函数
  • 复制对象,并从函数返回这个对象。

如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下:

classname (const classname &obj) {
   // 构造函数的主体
}

C++ 友元函数

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。

尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

#include <iostream>
using namespace std;
 
class Box
{
   double width;
public:
   friend void printWidth( Box box );
   void setWidth( double wid );
};

// 成员函数定义
void Box::setWidth( double wid )
{
    width = wid;
}

// 请注意:printWidth() 不是任何类的成员函数
void printWidth( Box box )
{
   /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
   cout << "Width of box : " << box.width <<endl;
}
 
// 程序的主函数
int main( )
{
   Box box;
   // 使用成员函数设置宽度
   box.setWidth(10.0);
   // 使用友元函数输出宽度
   printWidth( box );
   return 0;
}

C++ 内联函数inline

C++ 内联函数是通常与类一起使用。引入内联函数的目的是为了解决程序中函数调用的效率问题。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。内联函数的定义只能是一行(编译器能正确的替换)。

C++ 类的静态成员

使用 static 关键字来把类成员定义为静态的,当声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本,在创建第一个对象时,所有的静态数据都会被初始化为零。

不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符:: 来重新声明静态变量从而对它进行初始化。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问。

// 初始化类 Box 的静态成员
int Box::objectCount = 0;

静态成员函数与普通成员函数的区别:

  • 静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。

2. C++ 继承

class derived-class: access-specifier base-class, base-class

C++ 重载运算符和重载函数

C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载

//重载‘+’运算符,可以把 operator+ 当做函数名
Box operator+(const Box&);
Box operator+(const Box&, const Box&);

3. 多态

不同于 java,直接重写父类的同名函数,子类对象调用同名函数时被编译器设置为基类中的版本,这就是所谓的静态多态,或静态链接 – 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,因为函数在程序编译期间就已经设置好了。

虚函数

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。这种操作被称为动态链接,或后期绑定

纯虚函数

可以在基类中声明一个虚函数,以便在派生类中重新定义该函数更好地适用于对象,基类中又不对虚函数给出有意义的实现,这个时候就会用到纯虚函数。

class Shape {

   protected:

      int width, height;

   public:

      Shape( int a=0, int b=0)

      {

         width = a;

         height = b;

      }

      // pure virtual function

      virtual int area() = 0;//= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数。

};

C++ 接口(抽象类)

c++没有特定的关键字定义接口(抽象类)

C++ 接口是使用抽象类来实现的,如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 “= 0” 来指定的。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。

    原文作者:richy_
    原文地址: https://www.jianshu.com/p/b4d9ed2e305a
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞