14.拷贝构造函数、静态、友元和预编译头
- 拷贝构造函数
- 静态
- 友元
- 预编译头
拷贝构造函数
eg:
Playeer.h代码:
#pragma once class Playeer { private: int num; char* name; public: Playeer(int x, const char* name); ~Playeer(); void display(); // 输出结果 void setX(int x); // 改变num值 void setname(const char* name); // 改变name };
Playeer.cpp代码:
#include "Playeer.h" #include <string.h> #include <iostream> using namespace std; Playeer::Playeer(int n, const char* word) // 构造函数 { num = n; name = new char[20]; strcpy_s(name, 20, word); // 拷贝 } Playeer::~Playeer() { delete[] name; name = nullptr; } void Playeer::display() { cout << name << " " << num << endl; } void Playeer::setname(const char* word) { strcpy_s(name, 20, word); // 拷贝 } void Playeer::setX(int x) { num = x; }
源.cpp代码:
#include "Playeer.h" int main() { Playeer p1(10, "lisi"); Playeer p2 = p1; p1.display(); p2.display(); p1.setX(20); p1.setname("zhanssan"); p1.display(); p2.display(); }
运行结果:
但是此代码会引起,系统的奔溃,需要引入拷贝构造函数。
语法:
类名(const 类名 & 变量名);
拷贝构造函数的特性:
定义当一个对象初始化另一个对象时调用的不是构造函数,而是拷贝构造函数;
没定义拷贝构造函数时,系统会分配一个默认的拷贝构造函数;
浅拷贝
eg:在Playeer类中加入,拷贝构造函数
Playeer::Playeer(const Playeer& playeer) { num = playeer.num; name = playeer.name; // 浅拷贝 }
运行结果为
但程序依旧会奔溃,因为浅拷贝只是简单的改变值,没有影响地址
深拷贝
eg:
Playeer::Playeer(const Playeer& playeer) { num = playeer.num; //name = playeer.name; // 浅拷贝 name = new char[20]; strcpy_s(this->name, 20, playeer.name); }
运行结果为:
使用了深拷贝程序就没有奔溃。
静态
类的静态变量
类的静态变量,只会与类的运算一直变化。
语法:
static 变量名
eg:
未使用的静态变量
.h文件的代码
class number { int num=0; int id; public: number() { num++; id = num;} void show() { cout << "num:" << num << " " << "id:" << id << endl; } };
主程序代码
number cod,cod2;
cod.show();
cod2.show();
使用静态变量的
修改.h代码
class number { static int num; // 改为 int id; public: number() { num++; id = num;} void show() { cout << "num:" << num << " " << "id:" << id << endl; } };
修改.cpp文件代码
int number::num = 0;
运行结果
调用静态变量
如果静态变量在类的公共中,可以直接调用
语法:
类名::变量名;
eg:
number cod,cod2;
cod.show();
cod2.show();
cout << number::num << endl;
局部静态变量
eg:
int main() { int b; for (int i = 0; i < 8; i++) { static int number = 0; number++; b = number; } cout << b; }
运行结果为8
友元
在类中使用,可以让其他类和函数直接调用 类中的内容
eg:
class Num { public: friend void addone(Num a); friend class B; private: int data=9; }; class B { public: void addtwo(Num a) { a.data += 2; cout << a.data << endl; } private: }; void addone(Num a) { a.data++; cout << a.data << endl; } int main() { B i; Num j; addone(j); i.addtwo(j); }
预编译头文件
预编译头是可以不用重复include头文件的操作
选中项目,右键属性
打开属性后、点击c/c++---预编译头---预编译头,把不使用预编译头改为创建或使用、后点击应用
创一个与预编译头文件名相同的.h文件、将需要的include内容,或using namespace代入、先写程序自带的头文件、再写自己创建的类