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"
思考类的属性
构造例子:构造和析构