5、类的定义、类的实例化、string类的实现原理

类的定义

构造函数

  • 构造函数函数名必须与类名相同,且没有返回值类型
  • 构造函数在定义对象同时自动被调用,而且仅被调用一次
    • 对象定义语句
    • new操作符
  • 构造函数可以定义对象的各个成员变量并赋初值 (设置对象的初始状态)
  • 构造函数也可以在对象定义之初完成想实现的任何操作

5、类的定义、类的实例化、string类的实现原理_第1张图片

对象的定义过程

  1. 为整个对象分配内存空间
  2. 调用构造函数
    1. 定义成员变量
    2. 执行用户在构造函数中书写的代码
// 构造函数:(1)函数名必须和类名相同 (2)没有返回值类型
// 构造函数被调用的时间: 定义对象的同时,自动被调用
// 构造函数的作用:定义对象的每一个成员变量
#include 
#include 
using namespace std;
class  Human {
public:
    Human( /* Human* this  */ int age = 0, const char* name="匿名"){
        // 在this指向的内存空间中定义m_age(给m_age分类内存空间),初始值为随机数
        // 在this指向的内存空间中定义m_name(给m_name分配内存空间),初始值为随机数
        cout << "Human类的构造函数被调用" << endl;
        this->m_age = age;
        strcpy(this->m_name,name);
    }

    void getInfo(/* Human* this */){
        cout << "姓名: " << m_name << ", 年龄: "  << m_age << endl;
    }
private:
    int m_age;
    char m_name[256];
};

int main( void ) {
    Human h(22,"张三");  // 定义h(给h分配内存空间), 利用h.Human(22,"张三")
    cout << "h对象定义完毕" << endl;
//  h.setInfo(22,"张三");
    h.getInfo();

    return 0;
}

类的实例化

对象的定义与销毁

  • 在栈中定义单个对象

    • 类名 对象;
    • 类名 对象(实参表);
  • 在栈中定义对象数组

    • 类名 对象数组[元素个数]
    • 类名 对象数组[元素个数] = { 类名(实参表), …}
    • 类名 对象数组[] ={类名(实参表), …};
  • 堆中定义、销毁单个对象

    • 类名*对象指针 = new 类名;
    • 类名*对象指针 = new 类名 0;
    • 类名* 对象指针 = new 类名(实参表)
    • delete 对象指针:
  • 在堆中定义/销毁对象数组

    • 类名* 对象数组指针 = new 类名[元素个数];
    • 类名*对象数组指针 = new 类名[元素个数]{类名(实参表),…];// 需要编译器支持C++11标准
    • deletel[] 对象数组指针;

string类的内部实现原理

5、类的定义、类的实例化、string类的实现原理_第2张图片
string类定义对象的常见的5种方式:

  1. string(const char* psz=“” )
    string s1(“Hello”); // 定义s1,利用s1.string(“Hello”) -->s1维护的字符串为"Hello"

  2. string(const string& that )
    string s2(s1); // =s1; //定义s2,利用s2.string(s1) -->s2维护的字符串和s1维护的字符串内容相同

  3. operator=(s2)
    string s3; // 定义s3,利用s3.string() --> s3维护的字符串为空串
    s3 = s2; //触发operator=(s2) --> s3维护的字符串和s2维护的字符串内容相同

  4. 类型转换+初始化 =>string s4 = 匿名string类对象
    string s4 = “Hello”; // s4维护的字符串内容为"Hello"

  5. 类型转换+赋值
    string s5; // s5维护的字符串内容为空串
    s5 = “Hello”; // s5维护的的字符串内容为"Hello"

注意事项:(适用于所有类)

  • 如果在做初始化,并且"="两边类型完全一样,那么=xxx和(xxx)无差别
  • 如果在做赋值,并且"="两边类型完全一致,将触发operator=函数的调用
  • 无论初始化还是赋值,只要"="两边类型不一致,编译器首先要做类型转换操作
#include 
using namespace std;

// C++标准库设计的string类

int main( void ){
    string s1("Hello");  // 定义s1,利用s1.string("Hello") -->s1维护的字符串为"Hello"
    cout << "s1: " << s1 << endl;

    // 如果在做初始化,并且"="两边类型完全一样,那么=xxx和(xxx)无差别
    string s2(s1); // =s1;  //定义s2,利用s2.string(s1) -->s2维护的字符串和s1维护的字符串内容相同
    cout << "s2: " << s2 << endl;

    string s3; // 定义s3,利用s3.string() --> s3维护的字符串为空串
    cout << "s3被赋值前:" << s3 << endl;
    // 如果在做赋值,并且"="两边类型完全一致,将触发operator=函数的调用
    s3 = s2; //触发operator=(s2) --> s3维护的字符串和s2维护的字符串内容相同
    cout << "s3被赋值后:" << s3 << endl;

    // 无论初始化还是赋值,只要"="两边类型不一致,编译器首先要做类型转换操作
    string s4 = "Hello";//定义匿名string类对象,利用匿名string类对象.string("Hello")-->匿名string类对象维护的"Hello"
                        // string s4 = 匿名string类对象;--> s4维护的字符串和匿名string类对象维护的字符串内容相同
                        // -->s4维护的字符串内容为"Hello"
    cout << "s4: " << s4 << endl;

    string s5; // s5维护的字符串内容为空串
    s5 = "Hello"; // 定义匿名string类对象,利用匿名string类对象.strng("Hello")-->匿名string类对象维护"Hello"
                  // s5 = 匿名string类对象 --> s5维护的字符串和匿名string类对象维护的字符串内容相同
                  // --> s5维护的的字符串内容为"Hello"
    cout << "s5: " << s5 << endl;

    return 0;
}

你可能感兴趣的:(c++,算法)