C++中的类与构造函数
一、C++中类的常用写法
1、在头文件中声明类的属性和方法
如:MyTeacher.h
//防止重复引入
#pragma once
class MyTeacher{
private:
char* name;
int age;
public:
void setName(char* name);
char* getName();
void setAge(int age);
int getAge();
};
2、在源文件中(.cpp)实现对应的方法
如:MyTeacher.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "MyTeacher.h"
#include <iostream>
void MyTeacher::setName(const char* name) {
this->name = new char[100];
strcpy(this->name, name);
}
char* MyTeacher::getName() {
return this->name;
}
void MyTeacher::setAge(int age) {
this->age = age;
}
int MyTeacher::getAge() {
return this->age;
}
3、在具体C++代码中使用
如:test.cpp
#include "MyTeacher.h"
using namespace std;
void main() {
MyTeacher t;
t.setName("Jack");
t.setAge(25);
cout << t.getName() << "," << t.getAge() << endl;
getchar();
}
二、C++中类的构造函数、析构函数、拷贝构造函数
1、构造函数
- C++类默认有无参构造函数,重写无参构造函数会覆盖默认的无参构造函数
- 有参构造函数会覆盖默认无参构造函数
class Teacher{
private:
char* name;
int age;
public:
//无参构造函数
Teacher(){
cout << "无参构造函数" << endl;
}
//有参构造函数
Teacher(char *name,int age){
this->name = name;
this->age = age;
cout << "有参构造函数" << endl;
}
};
void main(){
Teacher t1;
Teacher t2("Rose",23);
//有参构造函数另一个调用方式
Teacher t3 = Teacher("jack",21);
getchar();
}
2、析构函数
当对象要被系统释放时,析构函数会被调用,一般用作善后处理
class Teacher{
private:
char* name;
int age;
public:
//无参构造函数
Teacher(){
this->name = (char*)malloc(100);
strcpy(name,"Hello,Jack Teacher");
this->age = 25;
cout << "无参构造函数" << endl;
}
//析构函数
~Teacher(){
cout << "析构函数" << endl;
free(this->name);
}
//有参构造函数
Teacher(char *name,int age){
this->name = name;
this->age = age;
cout << "有参构造函数" << endl;
}
};
void func(){
Teacher t1;
}
void main(){
func();
getchar();
}
3、拷贝构造函数
3.1 浅拷贝
- 默认拷贝构造函数,就是值拷贝(浅拷贝)
- 浅拷贝拷贝的是指针的地址(同一块内存区域)
using namespace std;
class Teacher {
private:
char* name;
int age;
public:
//有参构造函数
Teacher(char *name, int age) {
this->name = name;
this->age = age;
cout << "有参构造函数" << endl;
}
//析构函数
~Teacher() {
cout << "析构函数" << endl;
free(this->name);
}
//拷贝构造函数
Teacher(const Teacher &obj) {
this->name = obj.name;
this->age = obj.age;
cout << "拷贝构造函数" << endl;
}
void myprint() {
cout << name << "," << age << endl;
}
};
void main() {
Teacher t1((char*)"rose", 30);
Teacher t2 = t1;
t2.myprint();
getchar();
}
输出
有参构造函数
拷贝构造函数
rose,30
- 浅拷贝有可能会出现第二次释放变量导致出现异常的情况
例如:出现异常的情况
using namespace std;
class Teacher {
private:
char* name;
int age;
public:
//有参构造函数
Teacher(char *name, int age) {
int len = strlen(obj.name);
this->name = (char*)malloc(len+1);
strcpy(this->name,name);
this->age = age;
cout << "有参构造函数" << endl;
}
//析构函数
~Teacher() {
cout << "析构函数" << endl;
free(this->name);
}
void myprint() {
cout << name << "," << age << endl;
}
};
void func(){
Teacher t1((char*)"rose", 30);
Teacher t2 = t1;
t2.myprint();
}
void main() {
func();
getchar();
}
3.2 深拷贝
深拷贝拷贝的是指针指向的数据内容(两块内存区域)
using namespace std;
class Teacher {
private:
char* name;
int age;
public:
//有参构造函数
Teacher(char *name, int age) {
int len = strlen(obj.name);
this->name = (char*)malloc(len+1);
strcpy(this->name,name);
this->age = age;
cout << "有参构造函数" << endl;
}
//析构函数
~Teacher() {
cout << "析构函数" << endl;
free(this->name);
}
//拷贝构造函数(深拷贝)
Teacher(const Teacher &obj) {
//复制name属性
int len = strlen(obj.name);
this->name = (char*)malloc(len+1);
strcpy(this->name,obj.name);
this->age = obj.age;
cout << "拷贝构造函数" << endl;
}
void myprint() {
cout << name << "," << age << endl;
}
};
void func(){
Teacher t1((char*)"rose", 30);
//声明时会被调用
Teacher t2 = t1;
//下面这种方式不会被调用
//Teacher t1;
//Teacher t2;
//t1 = t2;
t2.myprint();
}
void main() {
func();
getchar();
}
3.3 拷贝构造函数被被调用的场景
- 声明时赋值
- 作为参数传入,实参给形参赋值
- 作为函数返回值返回,给变量初始化赋值
4、构造函数属性初始化列表
构造函数属性初始化列表的格式为:
[构造函数名称]([本类中属性列表],[第一个类对象的属性列表],[第二个类对象的属性列表]):[第一个类对象]([第一个类对象的属性列表]),[第二个类对象]([第二个类对象的属性列表]){
}
示例如下:
class Teacher{
private:
char* name;
public:
Teacher(char* name){
this->name = name;
cout << "Teacher有参构造函数" << endl;
}
~Teacher(){
cout << "Teacher析构函数" << endl;
}
char* getName(){
return this->name;
}
};
class Student{
private:
int id;
Teacher t1;
public:
Student(int id,char* t1_name) : t1(t1_name){
this->id = id;
cout << "Student有参构造函数" << endl;
}
~Student(){
cout << "Student析构函数" << endl;
}
void myprint(){
cout << this->id << "同学的老师是" << t1.getName() << endl;
}
};
void func(){
Student t1(16,(char*)"Jack");
t1.myprint();
}
void main(){
func();
getchar();
}
三、C++中的new 和 delete的使用
C++中通过new和delete来进行动态内存分配,new 和delete成对出现
C++中在使用new和delete会对应调用构造函数和析构参数,通过C中的malloc方式则不会调用构造函数和析构函数
class Teacher{
private:
char* name;
public:
Teacher(char* name){
this->name = name;
cout << "Teacher有参构造函数" << endl;
}
~Teacher(){
cout << "Teacher析构函数" << endl;
}
void setName(char* name){
this->name = name;
}
char* getName(){
return this->name;
}
};
void func(){
//初始化,返回指针地址
Teacher *t1 = new Teacher((char*)"Jack");
//使用
//释放
delete t1;
int *p2 = new int[10];
p2[0] = 11;
//释放数组
delete p2;
}
void main(){
func();
getchar();
}