C++:类和对象(2)

发布时间:2024年01月04日

目录

1.strcut和class的区别

2.将成员属性设置为私有

3.对象的初始化和清理

3.1 构造函数和析构函数

3.1.1?构造函数语法

3.1.2?析构函数语法

3.1.3?检验

3.2 构造函数的分类和调用

3.3 拷贝构造函数调用


1.strcut和class的区别

? ? ?struct和class的唯一区别在于默认的访问权限不同

? ? ?struct默认权限是公共 public

? ? ?class默认权限是私有 private

struct C1
{
   int a;
};
class  C2
{
   int a;
};
struct C1 c1;
c1.a=100;//在struct默认权限为公共,因此可以访问
C2 c2;
c2.a=100;//在class默认权限为私有,因此不能访问

2.将成员属性设置为私有

? ? ?优点1:将所有成员属性设置为私有,可以自己控制读写权限

? ? ?优点2:对于写权限,我们可以检测数据的有效性

#include<iostream>
using namespace std;
class Person
{
   //姓名设置可读可写
   void setName(string name)
   {
      _name=name;
   }
    void getName()
   {
     return _name;
   }

   //年龄设置只读 
   int getAge()
   {
     return _age;
   }

   //偶像设置只写 外界无法访问
   void setIdol(string idol)
   {
     _idol=idol;
   }
private:
   string _name;//可读可写
   int _age=18;//只读
   string _idol;//只写
};

3.对象的初始化和清理

? ? ?在生活中我们购买电子产品都会有出厂设置,我们如果不用了也要删除信息保证自己的隐私安全,C++的面向对象来源于生活,每个对象也会有初始化设置以及对象销毁前的清理数据的设置。

3.1 构造函数和析构函数

? ? ?一个对象或者变量没有初始状态,使用后果很未知,用完不进行清理。也有安全问题。C++利用构造函数析构函数解决问题,这两个函数被编译器自动调用,完成对象的初始化和清理工作。

如果我们自己不实现这两个操作,编译器会提供,但编译器提供的构造函数和析构函数是空实现

? ? ?构造函数:主要用于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用,当然也可以自己进行实现。

? ? ? 析构函数:主要用于对象销毁前系统自动调用,执行清理工作

3.1.1?构造函数语法
类名(){}
1.构造函数没有返回值,不用写void

2.函数名称与类名相同

3.构造函数可以有参数,因此可能有重载

4.程序在调用对象时会自动调用该函数,且只调用一次
3.1.2?析构函数语法
~类名(){}
1.构造函数没有返回值,不用写void

2.函数名称与类名相同,在名称前加上~

3.构造函数不可以有参数,因此不可能有重载

4.程序在对象销毁前会自动调用该函数,且只调用一次
3.1.3?检验
#include<iostream>
using namespace std;
class Person
{
public:
    //构造函数
    Person()
    {
        cout<<"Person 构造函数的调用"<<endl;
    }
    //析构函数
    ~Person()
    {
        cout<<"Person 析构函数的调用"<<endl;
    }
}
int main()
{
   Person p;//在栈上的数据,之后释放该对象
}

? ? ?输出:

Person 构造函数的调用
Person 析构函数的调用

? ? ?可以发现,我们只是创建了一个对象,并没有实现函数,这肯定是构造函数和析构函数被系统自动调用了啊,这两个函数都是必须有的,如果我们自己不提供,编译器给你提供,但都是空实现。

3.2 构造函数的分类和调用

? ? ?分类

? ? ? ? ? ?按参数分为:含参构造和无参构造 无参构造又称为默认构造函数

? ? ? ? ? ?按类型分为:普通构造和拷贝构造

? ? ?调用

? ? ? ? ? ? 括号法

? ? ? ? ? ? 显示法

? ? ? ? ? ? 隐式转换法

#include<iostream>
using namespace std;
class Person
{
public:
    //构造函数 普通构造
    Person()
    {
        cout<<"Person 无参(默认)构造函数的调用"<<endl;
    }
    Person(int a)
    {
        cout<<"Person 含参构造函数的调用"<<endl;
    }
     
    //拷贝构造函数
    Person(const Person &p)
    {
      cout<<"拷贝构造函数的调用"<<endl;
      age=p.age//将传入对象上的所有属性,拷贝到另一个人身上
    }

    //析构函数
    ~Person()
    {
       cout<<"析构函数的调用"<<endl;
    }
}  

//调用
void test()
{
    //括号法
    Person p1;//默认构造函数的调用
    Person p2(10);//含参构造函数的调用
    Person p3(p2);//拷贝构造函数的调用

    //显示法
    Person p1;
    Person p2=Person(10);//Person(10)为匿名对象 特点:当前行命令执行结束后,系统会马上回收匿名对象
    Person p3=Person(p2);//不能利用拷贝构造函数来初始化匿名对象,编译器会认为Person(p3)===Person p3;导致重定义

    //隐式转换法
    Person p4=10;//相当于Person p4=Person(10);
    Person p5=p4;
 }
int main()
{
    test();
}

3.3 拷贝构造函数调用

? ? ?C++拷贝构造函数通常是这三种情况:

1.使用一个已经创建完的对象来初始化一个新对象
2.值传递的方式给函数参数传值
3.以值方式返回局部对象

? ? ?以上面的class为例

1.使用一个已经创建完的对象来初始化一个新对象

Person p1;
Person p2(p1);

?2.值传递的方式给函数参数传值

void doWork(Person p)
{

}
void test()
{
   Person p;//调用默认构造函数
   doWork(p);//值传递 实参传给形参,调用拷贝构造函数
}

3.以值方式返回局部对象

Person doWork()//根据p1 创建出一个新对象返回 这肯定要调用拷贝构造函数
{
  Person p1; 
  return p1;
}
void test()
{
  Person p=doWork();
}
文章来源:https://blog.csdn.net/pancodearea/article/details/135396131
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。