「BUAA-C++」Lec2:C++的类


C++面向对象

  • 封装(一个类)
  • 继承(多类之间的父子关系)
  • 多态(行为关系)

C结构体 => C++类

C语言只可以封装struct关键字可以建立结构体

  • 结构体的最小内存单元以内存最大的成员类型为准
    struct Student {
        int i;
        int j;
        double d;
        char c;
    };
    // sizeof(struct Student) 结果为24
  • #pragma pack(1)可强制对齐

C语言中结构仅包含成员变量,与结构有关的函数均独立于结构之外(结构很散!

struct Student {
    int age;
    char *name;
};

void init(Student *s, int age, char *name) {
    s->age = age;
    strcpy(s->name, name);
}

C++在结构体中可以有成员变量和函数(attribute data member + funct member)

  • this指针永远自动的指向调用对象。

    struct Student {
        int age;
        char *name;
        void init(int age, char *name);
    };
    
    void Student::init(int age, char * name) {
        this->age = age;
        this->name = name;
    }

    C++的结构体把struct改为class, 结构体就变成了类

  • 类本身不占用内存空间,只是占用代码空间

C++类的特性

访问控制(access control)

  • private
  • public
  • protested
    通常情况下,需要把成员变量变为private, 函数一般为public;
    struct Student {
    
    private: //可以省略
        int age;
        char *name;
    
    public:
        //setter and getter;
        void setAge(int age);
        void init(int age, char *name);
    };
    

struct默认全部共有,class默认全部私有

构造函数(constructor

初始化尤为重要,每创建一个对象必须初始化;于是我们引入了构造函数;防止调用者不初始化直接调用(constructor),与类同名,可以传任意参数,没有返回值

struct Student {
private:
    int age;
    char *name;

public:
    //setter and getter;
    Student(int age, char *name);
    void setAge(int age);
    void init(int age, char *name);
};

类中默认有一个构造函数,与类同名, 没有参数,称为 默认构造函数(default constructor)。如果我们定义了一个构造函数,则默认构造函数自动会消失。构造函数的调用发生在对象创建之时。
有两种写法——

Student s(18, "hyggge");
Student *s = new Student(18, "hyggge");

一定要注意,如果想要通过默认构造函数或者无参构造函数来实例化对象,以下写法是错误的
Student s(); // error
Student s; // right
Student *s = new Student(); // right

临时变量和函数参数在桟上,malloc和new建立在堆区,全局变量建立在静态存储区

析构函数(destructor

类中可以定义一个析构函数,开头为~,与类同名, 无参数,无返回值。一个类中最多只有一个析构函数,如果不定义的话,默认调用缺省析构函数

class Student{
public:
    Student(){
        cout << "generate" << endl;
    }
    ~Student(){
        cout << "disappear" << endl;
    }
};

栈区普通对象会自己主动执行析构函数,而堆区的指针对象不会。就算运行到主函数结束(return之前),指针对象的析构函数也不会被执行,只有delete才可以触发析构函数。

int main() {
    Student s; //自动执行
    return 0;
}
int main() {
    Student *p = new Student();
    delete p; //只有执行了这一句,才会调用析构函数。
    return 0;    
}

当我们在类中有指针变量时,我们需要在自定义的析构函数中主动为指针变量释放空间(通过delete实现)。

class Student{
    int id;
    char* name;
public:
    Student(){
        cout << "generate" << endl;
    }
    ~Student(){
        delete name;
        cout << "disappear" << endl;
    }
};

判断:
析构函数可以有多个版本? No


作业:
自学udp socket:"hello world"
思考类的属性
构造例子:构造和析构


文章作者: Hyggge
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hyggge !
  目录