C++进阶学习一去不复返系列:类和对象(一)

C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,类的成员包含数据表示法和用于处理数据的方法(函数)。

类和对象

类定义

类定义是以关键字 class 开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表:

class ClassName
{
    public:
        memberType memberName1;
        .
        .
        .
        memberType memberNameN;

]

关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。也可以指定类的成员为 private 或 protected

对象定义

类提供了对象的蓝图,对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。对象定义的语法格式:

className objectName;

数据成员访问

类的对象的公共数据成员可以使用直接成员访问运算符 (.) 来访问。对于上面所述,举一个综合例子:

#include <iostream>
using namespace std;

class Box
{
   public:
      double length;   // 长度
      double breadth;  // 宽度
      double height;   // 高度
};
 
int main( )
{
   Box box;        // 声明 box对象,类型为 Box
   double volume = 0.0;     // 用于存储体积
 
   // box 详述
   box.height = 5.0; 
   box.length = 6.0; 
   box.breadth = 7.0;
 
   // box 的体积
   volume = box.height * box.length * box.breadth;
   cout << "box 的体积:" << volume <<endl;

   return 0;
}

注意:私有的成员和受保护的成员不能使用直接成员访问运算符 (.)来直接访问。

类成员函数

类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义。

1. 定义在类定义内部:

class Box
{
   public:
      double length;      // 长度
      double breadth;     // 宽度
      double height;      // 高度
   
      double getVolume(void)
      {
         return length * breadth * height;
      }
};

2. 在类的外部使用范围解析运算符 :: 定义成员函数:

class Box
{
   public:
      double length;      // 长度
      double breadth;     // 宽度
      double height;      // 高度
};
double Box::getVolume(void)
{
    return length * breadth * height;
}

调用成员函数是在对象上使用点运算符(.)。

类访问修饰符

数据封装是面向对象编程的一个重要特点,它防止其他非本类函数直接访问类的内部成员。关键字 public、private、protected 称为访问修饰符,访问权限从大到小:public > protected > private。成员和类的默认访问修饰符是 private。

公有(public)成员

公有成员在程序中类的外部是可访问的。在类外部,可以不使用任何成员函数,直接通过成员运算符(.)访问公有成员。访问公有成员就存在来两种方式:

#include <iostream>
using namespace std;

class Line
{
   public:
      double length;
      void setLength( double len );
};
 
void Line::setLength( double len )
{
    length = len;
}
 
// 程序的主函数
int main( )
{
   Line line;
   // 设置长度
   return 0;
}

通过成员函数:

line.setLength(6.0); 

直接访问公有成员:

line.length = 10.0; 

私有(private)成员

私有成员变量或函数在类的外部(类定义外)是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员。

默认情况下,类的所有成员都是私有的。实际操作中,我们一般会在私有区域定义数据在公有区域定义相关的函数,在类的外部用成员函数来访问私有成员。

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      double length;
      void setWidth( double wid );
      double getWidth( void );
 
   private:
      double width;
};
 
// 成员函数定义
void Box::setWidth( double wid ){
    width = wid;
}
 
// 程序的主函数
int main( )
{
   Box box;
 
   // length 是公有的,可以不使用成员函数设置长度
   box.length = 10.0; 
 
   //width 是私有的,使用成员函数才可以设置宽度
   box.setWidth(10.0);  // 
   return 0;
}

保护(protected)成员

保护成员变量或函数与私有成员十分相似,但有一点不同,保护成员在派生类(即子类)中是可访问的

保护成员可被派生类的任何成员函数访问:

#include <iostream>
using namespace std;
 
class Box
{
   protected:
      double width;
};
 
class SmallBox:Box // SmallBox 是派生类
{
   public:
      void setSmallWidth( double wid );
};
 
// 子类的成员函数 
void SmallBox::setSmallWidth( double wid ){
    //width是保护成员,子类的成员函数可以访问
    width = wid;
}
 
// 程序的主函数
int main( )
{
   SmallBox box;

   // 使用成员函数设置宽度
   box.setSmallWidth(5.0);
   return 0;
}

继承

创建类时,只需指定新建的类继承了一个已有的类的成员(数据成员和成员函数)即可。这个已有的类称为基类,新建的类称为派生类。继承代表了 is a 关系。例如,哺乳动物是动物,狗是哺乳动物,因此,狗是动物,等等。

基类 & 派生类

一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式如下:

//类 派生类: 访问修饰符 基类
class derived-class: access-specifier base-class

派生类继承了所有的基类方法,但下列情况除外:

  • 基类的构造函数、析构函数和拷贝构造函数。
  • 基类的重载运算符。
  • 基类的友元函数。

多继承

多继承即一个子类可以有多个父类,它继承了多个父类的特性。语法如下:

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
<派生类类体>
};

另外多继承(环状继承(继承链出现环)),A->D, B->D, C->(A,B)。

class D{......};
class B: public D{......};
class A: public D{......};
class C: public B, public A{.....};

这个继承当使用C创建对象的时候,会使D创建两个对象,要解决上面问题就要用虚拟继承虚继承——在创建对象的时候会创建一个父类对象的虚表),语法为:

class D{......};
class B: virtual public D{......};
class A: virtual public D{......};
class C: public B, public A{.....};

继承方式

因此具有public, protected, private三种继承方式,不大于继承方式的基类(父类)成员的访问属性不变,大于继承方式的基类(父类)成员的访问属性变成继承方式 (public > protected > private)。

  • 1.public 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected, private

  • 2.protected 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:protected, protected, private

  • 3.private 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:private, private, private

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

  • 1.private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;

  • 2.protected 成员可以被派生类访问。

如果继承时不显示声明是 private,protected,public 继承,则默认是 private 继承,而在 struct 中默认 public 继承

#include<iostream>
#include<assert.h>
using namespace std;
 
class A{
    public:
        int a;
        A(){
            a1 = 1;
            a2 = 2;
            a3 = 3;
            a = 4;
        }
    void fun(){
        cout << a << endl;    //正确
        cout << a1 << endl;   //正确
        cout << a2 << endl;   //正确
        cout << a3 << endl;   //正确
    }
    public:
      int a1;
    protected:
      int a2;
    private:
      int a3;
};

//public 继承
class B : public A{
    public:
        int a;
        B(int i){
            A();
            a = i;
        }
    void fun(){
        cout << a << endl;        //正确,public成员
        cout << a1 << endl;       //正确,基类的public成员,在派生类中仍是public成员。
        cout << a2 << endl;       //正确,基类的protected成员,在派生类中仍是protected可以被派生类访问。
        cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
    }
};

// protect继承
class B : protect A{
    public:
      int a;
        B(int i){
            A();
            a = i;
        }
    void fun(){
        cout << a << endl;        //正确,public成员。
        cout << a1 << endl;       //正确,基类的public成员,在派生类中变成了protected,可以被派生类访问。
        cout << a2 << endl;       //正确,基类的protected成员,在派生类中还是protected,可以被派生类访问。
        cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
  }
};

//private 继承
class B : private A{
    public:
        int a;
        B(int i){
            A();
            a = i;
        }
    void fun(){
        cout << a << endl;        //正确,public成员。
        cout << a1 << endl;       //正确,基类public成员,在派生类中变成了private,可以被派生类访问。
        cout << a2 << endl;       //正确,基类的protected成员,在派生类中变成了private,可以被派生类访问。
        cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
  }
};
int main(){
  B b(10);
  //类外可以访问public成员
  //类外不能访问protected成员
  //类外不能访问private成员
  cout << b.a << endl;
  cout << b.a1 << endl;  
  cout << b.a2 << endl;   
  cout << b.a3 << endl;   
  system("pause");
  return 0;
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

本节内容较多,篇幅过长,影响心情,请继续:C++进阶学习一去不复返系列:类和对象(二) <= 传送门

发布了161 篇原创文章 · 获赞 90 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_42415326/article/details/103999889