第六周嵌入式周结
C++的封装
一、构造函数
- 来初始化对象成员的值
- 作用:防止忘记初始化
- 特点:(1)函数名和类名相同(2)没有返回值(3)可以重载(4)自动调用
- 种类:默认无参构造函数、有参构造函数、类型转换构造函数、拷贝构造函数、移动拷贝构造函数。
无参构造函数(自定义/系统默认生成)
- Test() = default; 声明无参构造函数使用系统默认生成的。
- Test() = delete; 不让系统生成无参构造函数
#include <iostream>
using namespace std;
class Test
{
public:
//Test()//类里没有写构造函数,系统会默认给你生成一个无参的构造函数
//{
// cout << "Test" << endl;
//}
//Test() = default;//**声明**无参构造函数使用系统默认生成的。
//Test() = delete;//不让系统生成无参构造函数
int num;
int *name;
int age;
};
//默认无参构造函数
int main()
{
Test t;//有调用无参构造函数:默认无参构造函数(类里没有任何构造函数时,系统会默认生成。)
return 0;
}
有参构造函数
可以重载
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
Test() = default;//**声明**无参构造函数使用系统默认生成的。
Test(int num, const char *name, int age)
{
this -> num = num;
this -> age = age;
//this -> name = name;//error;
int len = strlen(name);
this ->name = new char[len+1];
strcpy(this->name,name);
cout << "Test in char* int" << endl;
}
Test(int num;int age)
{
this->num = num;
this->age =age;
cout << "Test int int" << endl;
}
int num;
int *name;
int age;
};
int main()
{
Test t;
Test t1(1,"zhangsan",21);//有参构造函数
Test t2(2,23);
return 0;
}
拷贝构造函数
- 默认拷贝构造函数:有指针 默认的拷贝函数会存在浅拷贝问题)
- 自定义拷贝函数:实现深拷贝
- 调用时机:
- 已有的对象初始化新的对象
- 传参:当形参为类的对象时,传参时会调用拷贝构造函数;
- 函数返回值为对象时;
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
Test()
{
this->name = nullptr;
cout << "Test" << endl;
}
//Test() = default;//**声明**无参构造函数使用系统默认生成的。
Test(int num, const char *name, int age)
{
this -> num = num;
this -> age = age;
//this -> name = name;//error;
int len = strlen(name);
this ->name = new char[len+1];
strcpy(this->name,name);
cout << "Test in char* int" << endl;
}
Test(int num;int age)
{
this->num = num;
this->age =age;
this ->name = nullptr;//t2
cout << "Test int int" << endl;
}
//深拷贝
Test(const Test &other)
{
this -> num = other.num;
this -> age = other.age;
//this -> name = other.name;
int len = strlen(name);
this ->name = new char[len+1];
strcpy(this->name,other.name);
cout << "Test copy Test" << endl;
}
~Test()
{
if(name != nullptr)
{delete [] name;}
//delete [] name;//释放name空间;会出问题;WHY??浅拷贝问题
cout << "~Test" << endl;
}
int num;
int *name;//指针 默认的拷函数会存在浅拷贝问题 string name;
int age;
};
int main()
{
Test t;//初始化
Test t1(1,"zhangsan",21);//有参构造函数
Test t2(2,23);
Test t3(t1);//t1的值赋给t3了
cout << t3.num << " " << t3.name << endl;
return 0;
}
类型转换构造函数
- 构造函数只有一个参数的,都是类型转换构造函数;用explicit防止发生类型转换。
- 危险(隐式类型转换:其他可以转换成类类型)
- explicit关键字 :防止发生隐式类型转换
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
Test() = default;//**声明**无参构造函数使用系统默认生成的。
Test(int num, const char *name, int age)
{
this -> num = num;
this -> age = age;
//this -> name = name;//error;
int len = strlen(name);
this ->name = new char[len+1];
strcpy(this->name,name);
cout << "Test in char* int" << endl;
}
Test(int num;int age)
{
this->num = num;
this->age =age;
cout << "Test int int" << endl;
}
explicit Test(int num) //防止发生隐式转换
{
this->num = 0;
this->age = 0;
this->name = nullptr;
cout << "Test int" << endl;
}
explicit Test(const char* name)
{
this->name = nullptr;
this->num = 0;
this->age = 0;
}
int num;
int *name;
int age;
};
int main()
{
Test t;
Test t1(1,"zhangsan",21);//有参构造函数
Test t2(2,23);
Test t4 = 1; //调用类型转换构造函数! 危险(隐式类型转换:其他可以转换成类类型)加explicit
Test t5(1);
Test t6 = "hello world";
return 0;
}
移动拷贝构造函数
- 解决临时对象拷贝效率问题;
代码片段:
void test1(Test t)//形参test1
{
cout << t.name << endl;
}
Test test2()
{
Test temp(1, "lisi", 24);
return temp;
}
Test t1(1, "zhangsan", 24);
test1(t1);//传参
Test t2 = test2();
return 0;
}
C/C++ 中static关键字的作用?
C/C++共有:
- 1、修饰全局变量时,表明一个全局变量只对定义在同一个文件的函数可见;
- 2、修饰局部变量时,表明该变量的值不会应为函数终止而丢失;
- 3、修饰函数时,表面该函数只在同一个文件中作用。
C++独有:
- 4、修饰类的成员
区别
- static关键词:C++里修饰成员变量,修饰成员方法;
- static修饰方法该方法属于类,不属于对象,没有this指针,只能访问static修饰的成员
- 不能访问非static成员可以通过类名::函数名访问
- 工程应用:static修饰方法为了兼容C/C++混合编程的(暂时没有学到,了解)
- static类成员变量,属于类,被这个类的所有对象共享;
注意事项:static修饰的成员必须在类外初始化;
工程应用:
- static修饰成员作用:实现对象通信。
- const关键词:修饰成员,修饰对象,修饰方法。
- const修饰的对象只能调用const成员方法;
- const修饰成员方法(必须在初始化列表中初始化)该成员方法只能使用成员变量的值,不能修改
- 加mutable关键字告诉编译器该成员可以在const方法中被修改
二、析构函数—释放对象成员所分配的内存空间
- 特点:函数名是类名;无参;不可重载;没有返回值。 当对象被释放,会调用析构函数
- 引入目的:防止内存泄漏。
#pragma warning(disable:4996)
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
Test()//类里面不构造这个函数,系统会给你默认构造这个函数
{
this->name = nullptr;
cout << "Test" << endl;
}
//Test() = default; //声明无参构造函数使用系统默认生成的;
//Test() = delete;//不让系统默认生成无参构造函数
Test(int num, const char* name, int age)
{
this->num = num;
this->age = age;
//this->name = name;//error;
int len = strlen(name);
this->name = new char[len + 1];
strcpy(this->name, name);.
cout << "Test int char * int" << endl;
}
Test(int num, int age)
{
this->num = num;
this->age = age;
this->name = nullptr;
cout << "Test int int" << endl;
}
Test(const Test& other)
{
this->num = other.num;
this->age = other.age;
//this->name = other.name;
int len = strlen(other.name);
this->name = new char[len + 1];
strcpy(this->name, other.name);
cout << "Test copy Test" << endl;
}
explicit Test(int num) //防止发生隐式转换
{
this->num = 0;
this->age = 0;
this->name = nullptr;
cout << "Test int" << endl;
}
explicit Test(const char* name)
{
this->name = nullptr;
this->num = 0;
this->age = 0;
}
Test(Test&& other)//移动拷贝拷贝构造函数
{
this->num = other.num;
this->age = other.age;
this->name = other.name;
other.name = nullptr;
cout << "Test copy Test &&" << endl;
}
~Test()
{
if (name != nullptr)
{
delete[] name;
}
cout << "~Test" << endl;
}
int num;
char* name;//string name;
int age;
};
//无参构造函数:系统默认生成、自定义 (default、delete)
//有参构造函数:可以重载;
//拷贝构造函数(用已有的对象初始化新的对象):默认拷贝构造函数(问题:浅拷贝问题) 自定义拷贝构造函数(深拷贝)
//拷贝构造函数的调用时机:
//1用已有的对象初始化新的对象
//2传参:当形参为类的对象时,传参时会调用拷贝构造函数;
//3函数返回值为对象时;
//类型转换构造函数:构造函数只有一个参数的,都是类型转换构造函数;用explicit防止发生类型转换;
//移动拷贝构造函数: 解决临时对象拷贝效率问题;
void test1(Test t)
{
cout << t.name << endl;
}
Test test2()
{
Test temp(1, "lisi", 24);
return temp;
}
int main()
{
#if 0
Test t; //调用无参构造函数:默认的无参构造函数(类里没有任何构造函数时,系统会默认生成)
Test t1(1, "zhangsan", 21); //有参构造函数
Test t2(2, 23);
Test t3(t1);
//cout << t3.num << " " << t3.name << endl;
//Test t4 = 1; //调用类型转换构造函数! 危险(隐式类型转换:其他可以转换成类类型)
Test t5(1);
//Test t6 = "hello world";
Test t7;
//t7 = 1;
#endif
Test t1(1, "zhangsan", 24);
test1(t1);
Test t2 = test2();
return 0;
}