C++ -类和对象基础.1

C++面向对象的三大特性:封装、继承、多态

封装

封装的意义: 将类中的属性和行为看成一个整体,用来表示事物; 对属性和行为的权限加以约束

类的设计:  语法: class  类名 { 权限 ;  属性 / 行为 };

class Person
{
    public:
       int m_A // 属性
      void test()  // 行为
{     
        cout << m_A << endl;        
}
};

类中的访问权限有三种:

(1)public 公共权限: 类外类内都可以访问

(2)protected 保护权限: 类内可以访问,类外不可以访问

(3)private 私有权限: 类内可以访问,类外不可以访问

protected 和 private的区别在于: protected 儿子可以访问父亲的保护权限 ;而private 儿子不可以访问父亲的私有权限。

class Person
{
     public:
       int m_name;
    protected:
       string lover;
    private:
  int password;
public:
void test()
{
     m_name = "张三“;
     lover = "张 " ;
     password = 123456;
}
};
void test()
{
   Person p1;
   cout << p1.m_name << endl;  // 可以访问
  p1.password; 
  p1.lover ; // 不可以访问  因为private 和 public 权限不允许在类外访问
}

在C++中 struct 和 class 的区别是: 默认访问权限不同, class 默认私有权限; struct 默认公共权限。

成员属性私有化:可以控制属性和行为的读写权限;对于写权限可以检测有效性;

通过在类内 函数实现成员属性和行为的读和写,通过函数检测写的有效性;

类中的属性和行为我们统一叫成员, 属性又叫 成员属性 或 成员变量; 行为叫成员函数 or 成员方法。

对象特性

对象的初始化和清理,C++中每个对象都有初始值的设置 和 销毁前清理数据的设置

构造函数和析构函数

构造函数:主要在创建对象时 为对象的成员属性赋值,系统自动调用且只调用一次;

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

析构函数和构造函数都是已经有的实现,如我们自己不提供,编译器会提供一个空实现

构造函数:

函数没有返回值 也不写void  ;函数名与类名相同;函数可以有参数 可以发生函数重载;编译器在调用对象时自动调用构造函数且只调用一次。

析构函数:

函数没有返回值也不写void; 函数名与类名相同在名称前加 ~;函数不可以有参数 也不能发生函数重载, 编译器在对象销毁前自动调用析构函数 且只调用一次

class Person
{
    public:
    Person()
{
    cout << "构造函数的调用" << endl;
}
    ~Person()
{
     cout << "析构函数的调用" << endl;
}
};

构造函数的调用及分类: 

按参数分: 有参构造   、 无参构造(默认构造)

按类型分: 普通构造 、 拷贝构造

调用: 括号法 显示法 隐式转换法

class Person
{
     public:
  Person ()
{
   cout << "默认构造函数(无参构造)" << endl; 
}
  Person(int a)
{
   cout << "有参构造函数的调用" << endl;
   m_A =a;
}
   Person(const Person &p)
{ 
       m_A = p.m_A;
     cout << "拷贝构造函数的调用" << endl;
}
   ~Person()
{
     cout << "析构函数的调用" << endl;
 }
int m_A;
};
int main()
{
      Person p1;
     Person p2(10);
    Person p3(p2) ;  // 括号法调用各构造函数
 // 默认函数构造 不能加 括号;因为编译器会认为这是一个函数的声明 
  
   // 显示法调用
    Person p4 = Person (10) ;  
    Person p5 = Person (p4);
// 数据类型 () 表示一个匿名对象, 如 Person(10); 匿名对象见名知意 就是无名字,
// 不能用拷贝函数来初始化匿名对象 如: Person(p1) 编译器会认为是: Person p1 ; 会认为是对象的声明

// 隐式转换法调用
    Person p6 = 10; 
    Person p7 = p6;  // 相当于 Person p7 = Person (p6);
return 0;
}

拷贝函数的调用时机

C++中调用拷贝构造函数通常有三种情况: 

(1)使用一个已经创建完毕的对象来初始化一个对象(赋值 )

(2)值传递时给函数参数传值

(3)以值的方式返回局部对象

Person test ()
{
   Person p;
   return p;  //以值的方式返回局部对象 时 调用拷贝构造函数 
}   // 拷贝构造函数本质是将值拷贝一份 赋值给新的对象或参数, 并不是把对象本身或参数本身传递过去

构造函数的调用规则

默认情况下: C++ 中一般给类添加至少四个函数

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

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

(3)默认拷贝构造函数, 对值进行简单的拷贝操作

(4)默认赋值运算符重载 operator= ,对属性进行值拷贝

调用规则如下:

如果用户自己定义了有参构造函数,那么编译器不会提供默认构造函数(无参构造),但是会提供拷贝构造函数。

如果用户自己定义了拷贝构造函数, 那么编译器不会提供默认构造函数和有参构造函数,需要自己定义。

深拷贝和浅拷贝

面试中常见的问题; 浅拷贝: 简单的赋值拷贝  ; 深拷贝: 在堆区重新开辟空间,进行拷贝赋值

析构函数的作用:用来释放堆区开辟的空间

class Person 
{
   public:
  Person(int a, int b)
{
  m_A = a;
  m_B = new int (b); // 给值b在堆区开辟一块空间存放在m_B中
}
  Person (const Person &p)
{
   cout << "拷贝函数的调用" << endl;
   m_A =p.m_A;
   m_B = new int (p.m_B);  //重新开辟一块空间给对象属性,防止浅拷贝带来的问题
}
  ~Person()
{
   cout << "析构函数的调用" << endl;
   if (m_B != NULL)
   {
      delete m_B ; //释放掉m_B存放的空间
      m_B = NULL;
}
}
 int m_A ;
int *m_B ;
};
int main()
{
    Person P1(10);
    Person P2(p1); //
   
    return 0;
}

初始化列表:语法: 构造函数 () : 属性1(值1),属性2 (值2)  { }

class Person
{
   public:
   Person(int a, int b) : m_A(a),m_B(b) { }
   int m_A;
   int m_B;
};

类中的成员可以是另一个类中的对象。称为对象成员

调用时:先调用对象成员的构造函数 在调用本类的构造函数;析构函数调用相反

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值