C++练级之路——类和对象(中)

简介: C++练级之路——类和对象(中)

1、六个默认成员函数

       我们创建一个类,如果我们什么都不写,类会自动生成六个默认成员函数;


接下来一个一个了解;

2、构造函数


       构造函数是一个特殊的函数,函数名和类名相同,主要是对类的初始化;


class Date
{
public:
  // 1.无参构造函数
  Date()
  {
    
  }
  // 2.带参构造函数
  Date(int year, int month, int day)
  {
    _year = year;
    _month = month;
    _day = day;
  }
  void Print()
  {
    cout << _year << "--" << _month << "--" << _day << endl;
  }
private:
  int _year;
  int _month;
  int _day;
};


构造函数的特性:


1.函数名和类名相同,无返回值,构造函数可以重载;

2.构造函数分为无参构造和有参构造;

3.有参构造还可以用缺省值;


例如:

//3.带缺省值的有参构造
Date(int year=2024, int month=4, int day=10)
{
  _year = year;
  _month = month;
  _day = day;
}


4.无参构造和全缺省构造不能同时调用,会报错,编译器会不知道该调用哪个;

5.如果没有写构造函数,编译器会自动生成一个构造函数,


注意:C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在

类中声明时可以给默认值。

例如:

private:
  int _year=1;
  int _month=1;
  int _day=1;


总结:

1、一般情况下构造函数需要我们自己去写;

2、只有少数情况下可以让编译器自动生成构造函数,类似MyQueue,成员全是自定义类型;

class stack
{
  //
};
class MyQueue
{
private:
  stack _st1;
  stack _st2;
};


3、析构函数


析构函数在类结束后清理调用的资源;

特性:

1.析构函数名是在类名前加上字符‘~';

2.无参数,无返回值;

3.一个类只有一个析构函数,若没有显式定义,编译器自动生成析构函数,析构函数不能重载;

4.对象生命周期结束后,编译器自动调用析构函数;

5.当类中没有申请资源时,可以不写析构函数,例如Date类,有资源申请时一定要写,否则会造成资源泄露,如stack;


4、拷贝构造


拷贝构造函数:只有一个形参;

特性:

1.拷贝函数也是构造函数的重载,

2.拷贝构造函数参数只能有一个,必须是类类型对象的引用,如果直接传类,编译器会报错,会引发无穷递归;

3.如果没有显式定义,编译器会自动生成默认的拷贝函数,默认的拷贝函数是浅拷贝或者值拷贝,就是不额外开辟空间,遇到一些需要额外开辟空间的类就不适用了;

class Date
{
public:
  //有参构造函数
  Date(int year=2024, int month=4, int day=11)
  {
    _year = year;
    _month = month;
    _day = day;
  }
  //拷贝构造函数
    //d是d1的引用
  Date(Date& d)
  {
    _year = d._year;
    _month = d._month;
    _day = d._day;
  }
  void Print()
  {
    cout << _year << "-" << _month << "-" << _day << endl;
  }
 
private:
  int _year;
  int _month;
  int _day;
};
 
int main()
{
  Date d1;
  d1.Print();
  Date d2 = d1;
  d2.Print();
 
  return 0;
}


注意:

类中如果没有涉及资源申请,可以不写拷贝构造函数,一旦涉及到资源申请,拷贝函数就是要写的,否则就是浅拷贝;

例如:

typedef int DataType;
 
class Stack
{
public:
  Stack(size_t capacity = 3)
  {
    cout << "Stack(size_t capacity = 3)" << endl;
 
    _array = (DataType*)malloc(sizeof(DataType) * capacity);
    if (NULL == _array)
    {
      perror("malloc申请空间失败!!!");
      return;
    }
    _capacity = capacity;
    _size = 0;
  }
 
  void Push(DataType data)
  {
    // CheckCapacity();
    _array[_size] = data;
    _size++;
  }
 
  void Print()
  {
    for (int i = 0; i < _size; i++)
    {
      cout << _array[i] << " ";
    }
    cout << endl;
  }
  // 其他方法...
  ~Stack()
  {
    cout << "~Stack()" << endl;
 
    if (_array)
    {
      free(_array);
      _array = NULL;
      _capacity = 0;
      _size = 0;
    }
  }
private:
  DataType* _array;
  int _capacity;
  int _size;
};
int main()
{
  Stack d1;
  d1.Push(1);
  d1.Push(2);
  d1.Push(3);
  d1.Print();
  Stack d2 = d1;
  d2.Print();
  return 0;
}


该程序会发生崩溃,因为没有写拷贝构造函数,编译器默认的拷贝构造是浅拷贝,导致d1和d2指向同一块空间,调用两次析构函数析构同一块空间,程序崩溃;

相关文章
|
10天前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
56 30
|
24天前
|
C++
C++(十一)对象数组
本文介绍了C++中对象数组的使用方法及其注意事项。通过示例展示了如何定义和初始化对象数组,并解释了栈对象数组与堆对象数组在初始化时的区别。重点强调了构造器设计时应考虑无参构造器的重要性,以及在需要进一步初始化的情况下采用二段式初始化策略的应用场景。
|
24天前
|
存储 编译器 C++
C ++初阶:类和对象(中)
C ++初阶:类和对象(中)
|
24天前
|
C++
C++(十六)类之间转化
在C++中,类之间的转换可以通过转换构造函数和操作符函数实现。转换构造函数是一种单参数构造函数,用于将其他类型转换为本类类型。为了防止不必要的隐式转换,可以使用`explicit`关键字来禁止这种自动转换。此外,还可以通过定义`operator`函数来进行类型转换,该函数无参数且无返回值。下面展示了如何使用这两种方式实现自定义类型的相互转换,并通过示例代码说明了`explicit`关键字的作用。
|
24天前
|
存储 设计模式 编译器
C++(十三) 类的扩展
本文详细介绍了C++中类的各种扩展特性,包括类成员存储、`sizeof`操作符的应用、类成员函数的存储方式及其背后的`this`指针机制。此外,还探讨了`const`修饰符在成员变量和函数中的作用,以及如何通过`static`关键字实现类中的资源共享。文章还介绍了单例模式的设计思路,并讨论了指向类成员(数据成员和函数成员)的指针的使用方法。最后,还讲解了指向静态成员的指针的相关概念和应用示例。通过这些内容,帮助读者更好地理解和掌握C++面向对象编程的核心概念和技术细节。
|
1月前
|
存储 算法 编译器
c++--类(上)
c++--类(上)
|
1月前
|
编译器 C++
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
|
24天前
|
存储 C++
C++(五)String 字符串类
本文档详细介绍了C++中的`string`类,包括定义、初始化、字符串比较及数值与字符串之间的转换方法。`string`类简化了字符串处理,提供了丰富的功能如字符串查找、比较、拼接和替换等。文档通过示例代码展示了如何使用这些功能,并介绍了如何将数值转换为字符串以及反之亦然的方法。此外,还展示了如何使用`string`数组存储和遍历多个字符串。
|
1月前
|
存储 C++
C++ dll 传 string 类 问题
C++ dll 传 string 类 问题
20 0
|
1月前
|
存储 安全 编译器
【C++】类和对象(下)
【C++】类和对象(下)
【C++】类和对象(下)