c++之 类和对象

简介: c++之 类和对象

1.类和对象的基本概念

1.c语言与c++中的结构体

我们知道在c语言里,我们是无法在结构体内部定义函数的,但在c++里,我们可以定义函数。从这里我们就可以看出c++对于数据(属性)和行为(方法)是封装的。它可以在数据的储存里同时添加了数据操作的功能。

所谓封装就是将抽象得到的数据和行为相结合,形成一个有机体,及就是将数据与操作数据的函数代码进行有机的结合,形成类,其中的数据和函数都是类的成员。

c语言中结构体中不能存放函数,也就是数据(属性)和行为(方

法)是分离的

c++中结构体中是可以存放函数的,也就是数据(属性)和行为

(方法)是封装在一起的。

所以了解c++中的类是至关重要的。

2.类的封装性

c++将事物的属性和行为封装在一起

类和结构体的一个区别在于,类对成员可以进行访问的权限控

制,结构体不可以

类 = 类型 (事物的行为和属性) 类实例化出来的变量叫对象

类中的函数 可以访问类里面的成员

类将具有共性的数据和方法封装在一起,加以权限区分,用户只能通过公共的方法访问私有数据。

类的权限分为:private (私有)  ,public (公有), protected(保护)三种权限。

这些权限是针对类外部的访问,只有公有(public)数据才能被访问,在没有涉及到继承与派生是,private和protected是同等级的,外部都不允许访问,要想访问到该成员,只能通过公有的方式间接访问到这两类数据。

0e7169ad77f94b9684051b43c02812c6.png

3.定义类

类的关键字 class ,类的定义方式为:

class 类名

{

    成员列表

}

c++中对事物的封装 将属性和行为封装在一起

类 将事物抽象成属性和行为,并且封装在一起

类中定义的成员不声明权限,默认为私有型。

举个例子:

/定义一个类
class Data
{
private:
  int a;//私有数据  也是默认的类型
protected:
  int b;//保护数据
public:
  int c;//公有数据
  void showdata()//方法
  {
    cout << a << " " << b << " " << c << endl;
  }
};
//使用类
int main()
{
  //定义Data类的一个对象
  Data data;
  //只能访问公有的数据
  cout << data.c<<endl;
  //通过公有的方法实现间接访问私有的数据
  data.showdata();
  //打印data中的a,b,c。
}

结构体中所有成员默认都是公有的 而类中的所有成员默认是私有的,且在结构体中也可以修改成员的访问权限。

设计一个类需要我们对该类的方法与数据做出详细的判断,比如设计一个人的类

class person
 { 
 private:
   char pname[20];
   int page;
   char pIDnumber[10];
 public:
   void Initperson(char* name,int age,  char *IDnumber)//初始化person
   {
     strcpy(pname, name);
     if (age > 0)
     {
            page = age;
     }
     else
     {
       cout << "错误格式" << endl;
     }
     strcpy(pIDnumber, IDnumber);
   }
   //修改名字
   void setname(char *arr)
   {
     strcpy(pname, arr);
   }
   //修改年龄
   void setage(int age)
   {
     if (age > 0)
     page = age;
   }
   //修改身份号码
   void setIDnumber(char* arr)
   {
     strcpy(pIDnumber, arr);
   }
   //打印信息
   void showperson()
   {
     cout << "姓名:" << pname << endl;
     cout << "年龄:" << page << endl;
     cout << "身份号码:" << pIDnumber << endl;
   }
 };
 int main()
 {
   //定义两个person类的对象
   person jack;
   //初始化
   jack.Initperson((char*)"jack", 12,(char *)"123456");
   jack.setage(18);
   jack.showperson();
   return 0;
 }

尽量设置成员变量为私有权限

设置成员变量为私有,优点:

对变量的设置时的控制

可以给变量设置只读权限

可以给变量设置只写权限

可以给变量设置可读可写权限

当然我们也可以类外实现方法-即函数,不过我们需要添加作用域符来表明所属地。

class Data
   {
   private:
    int a;//私有数据  
   protected:
    int b;//保护数据
   public:
    int c;//公有数据
    void showdata()//方法
    {
      cout << a << " " << b << " " << c << endl;
    }
    void getA(int a);
   };
 void Data::getA(int A)
 {
   a = A;
 }

4.构造与析构

构造与析构的概念:

创建对象时,对对象进行初始化的工作,就是构造

销毁对象时对对象进行清理工作,就是析构

一般需要人为提供,如果不提供,那么编译器也会给提供,只是编译器提供的构造和析构函数不会做任何操作,只是默认为空。若创建有构造函数与析构函数,编译器会自动调用构造函数与析构函数。

创建对象时和释放对象时,构造函数和析构函数自动会调用,不 需要人为调用。

构造函数的特点:

1.没有返回值

2.没有函数返回类型

3.函数名与类名一样

4.可以发送函数重载

5.创建对象时,会自动调用。

析构函数的特点:

没有返回值

1.函数名: 类名前面加上~

2.没有参数

3.不能发送函数的重载

4.销毁对象之前,回被自动调用

构造函数

构造函数的几种方式:

class Data
   {
   private:
    int a;//私有数据  
   protected:
    int b;//保护数据
   public:
     Data()//无参构造函数
     {
       c= 0;
     }
    int c;//公有数据
    Data(int x,int y)//有参构造函数
    {
      c = x;
             a=y;
    }
   };
  int main()
  {
    //隐式调用无参构造函数(未创建构造函数,构造函数默认为无参的)
    Data b1;
    //显示调用无参构造函数
    Data b2=Data();
    //隐式调用有参构造函数
    Data b3(1,2);
    //显式调用有参构造函数
    Data b4 = Data(1,2);
    //匿名对象(无名构造对象)  存活周期为当前语句结束,立即释放
    Data();
    Data(20,10);
    //构造函数隐式转换(类中只有一个数据成员)
    Data b5 = 100;
 }

构造函数的分类

无参构造和有参构造

普通沟通和拷贝构造

拷贝构造函数的写法: 类名 ( const 类名 & obj ){}

注意:

如果自定义了一个构造函数,系统将不再提供默认的构造函数.

如果自定义了一个拷贝构造,系统将不再提供默认的拷贝构造.

默认的拷贝构造是简单的值拷贝.

如果创建对象时,不能调用对应的构造函数,将不能创建出对象.

我们要习惯去在构建类时,把构造函数也构建了。

析构函数

函数名称与类名相同,在函数名前加~,没有返回类型,没有函数形参,不能被重载。

当对象生命周期结束时,系统自动调用析构函数。

先调用析构函数,在释放对象空间。

析构函数的定义

 class Data1
   {
   private:
    int a;//私有数据  
   protected:
    int b;//保护数据
   public:
     Data1(int x)//有参构造函数
     {
       c= x;
       cout << "构造函数:" << c << endl;
     }
     int c;
     ~Data1()//析构函数
     {
      cout<<"析构函数:"<<c<<endl;
     }
   };
  Data1 b1(10);//整个项目结束时才会析构
  void test1()
  {
    Data1 b2(20);
     {
      Data1 b3(30);//局部对象 (出了范围就会自动调用析构函数销毁)
     }
    Data1 b4(40);
  }
  int main()
  {
    test1();
    return 0;
  }

运行来通过打印顺序发现函数调用顺序:


0de864cdfb814c4d8f972a6d1431871f.png

一般析构函数为空,这里只是展示一下调用关系才写了打印功能。

一般不写析构函数,但若存指针,必须要写析构函数,因为所在堆区空间,默认是无法释放的,会造成内存泄漏,我们要创建析构函数释放这一部分空间。

拷贝构造函数

拷贝构造:本质是构造函数

拷贝构造函数的写法:

类名(const 类名 &obj){}

拷贝构造函数的调用时机

总结一种情况: 旧对象初始化新对象

分类:

旧对象初始化新对象

形参是一个对象

返回局部对象

c++默认增加的函数

默认情况下, c++ 编译器至少为我们写的类增加 3 个函数

1 .默认构造函数 ( 无参,函数体为空 )

2 .默认析构函数 ( 无参,函数体为空 )

3 .默认拷贝构造函数,对类中非静态成员属性简单值拷贝

如果用户定义拷贝构造函数, c++ 不会再提供任何默认构造函数

如果用户定义了普通构造 ( 非拷贝 ) , c++ 不在提供默认无参构造,但是

会提供默认拷贝构造.

类对象成为另一个类的成员

类中有多个对象时,构造的顺序是先构造里面的对象,在构造外

面的对象.

类中有多个对象时,析构时顺序是先析构外面的对象,在析构里

面的对象.


相关文章
|
2月前
|
编译器 C++
C++之类与对象(完结撒花篇)(上)
C++之类与对象(完结撒花篇)(上)
36 0
|
19天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
49 4
|
20天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
46 4
|
2月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
28 4
|
2月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
25 4
|
2月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
2月前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
2月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
54 1
|
2月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
20 1
|
2月前
|
存储 编译器 C语言
【C++打怪之路Lv3】-- 类和对象(上)
【C++打怪之路Lv3】-- 类和对象(上)
17 0