C++进阶语法——OOP(面向对象)【学习笔记(四)】

文章目录

      • 1、C++ OOP⾯向对象开发
        • 1.1 类(classes)和对象(objects)
        • 1.2 public、private、protected访问权限
        • 1.3 实现成员⽅法
        • 1.4 构造函数(constructor)和 析构函数(destructor)
          • 1.4.1 构造函数(constructor)
          • 1.4.2 析构函数(destructor)
        • 1.5 代理构造函数(delegating constructor)
        • 1.6 拷⻉构造函数(copy constructor)
        • 1.7 浅拷贝(shallow copy)和深拷贝(deep copy)
          • 1.7.1 浅拷⻉(shallow copy)
          • 1.7.2 深拷⻉(deep copy)
        • 1.8 在类中使⽤const
        • 1.9 在类中使⽤static
        • 1.10 struct 和 class区别

1、C++ OOP⾯向对象开发

1.1 类(classes)和对象(objects)

简单介绍一下类:

• C++ 类(classes)
------->• 创建对象⽤的蓝图(blueprint)
------->• ⽤户⾃定义的数据类型
------->• 有成员属性(data)和成员⽅法(methods)
------->• 可以隐藏属性和⽅法(private)
------->• 可以提供公共接⼝(public)
示例: Account, Student, std::vector, std::string

简单介绍一下对象:

• C++ 对象(objects)
------->• 由类创建⽽来
------->• 表示类的⼀个具体的实例(Instance)
------->• 可以有很多个实例,每个都有独⽴的身份
------->• 每个对象都可以使⽤类中定义的⽅法
• Account对象示例:
------->• Jobs、Alice 的account是Account类的实例
------->• 每个实例都有它的余额、可以提现、存钱

虽然 int 不是类,这里把它看成一个类,int 后面的 high_score 和 low_score 可以看成 int 类实例化后的对象;
创建 Account 类后,实例化2个对象,分别是:jobs_account 和 alice_account;
std是类,后面跟着的容器 vector 和字符串 string 是对象;
如下图所示,

在这里插入图片描述

A、声明一个类:

在这里插入图片描述

B、创建类的对象:

还可以根据类创建一个指针,并且在堆上使用关键字 new 动态分配内存空间,使用后用 delete 删除释放内存空间,

在这里插入图片描述

一旦有了类的对象,就可以像 C++ 其他变量去使用

在这里插入图片描述

代码:

#include <iostream>
#include <string>
#include <vector>using namespace std;class Account
{// 属性string name {"None"};double balance {0.0};// 方法bool deposit(double amount); // 存款bool withdraw(double amount); // 取款
};int main()
{Account jobs_account;  // 初始化属性Account alice_account;  // 初始化属性Account accounts [] {jobs_account, alice_account}; // 数组vector<Account> accounts_vec {jobs_account}; // vectoraccounts_vec.push_back(alice_account);Account *p_account = new Account(); // 指针delete p_account;return 0;
}

C、获取类的属性或⽅法:

使⽤点操作符:

在这里插入图片描述

如果是⼀个指向对象的指针,可以解引⽤或者使⽤箭头操作符,
需要注意: 使用 . 操作符的时候需要在前面加一个括号 () ,因为 . 操作符的优先级高于 * 解引用运算符的优先级,

在这里插入图片描述

代码:

#include <iostream>
#include <string>
#include <vector>using namespace std;class Account
{
public:    // 属性string name {"None"};double balance {0.0};// 方法bool deposit(double amount){balance += amount;cout << name << "刚存入" << amount << "元,现在余额为" << balance << "元" << endl;return true;}; // 存款bool withdraw(double amount){if (balance >= amount){balance -= amount;cout << name << "刚取出" << amount << "元,现在余额为" << balance << "元" << endl;return true;} else {cout << name << "余额不足,取款失败" << endl;return false;}}; // 取款
};int main()
{Account jobs_account;jobs_account.name = "Jobs";jobs_account.balance = 1000.0;jobs_account.deposit(500.0);Account *alice_account = new Account();(*alice_account).name = "Alice";alice_account->balance = 2000.0;(*alice_account).deposit(1000.0);alice_account->withdraw(500.0);return 0;
}
1.2 public、private、protected访问权限

• public
----->• 可以被任何实体访问
• private
----->• 只能被本类的⽅法访问
• protected
----->• 可以被本类和⼦类(继承)的⽅法访问

在这里插入图片描述

在这里插入图片描述

代码:

#include <iostream>
#include <string>
#include <vector>using namespace std;class Account
{
private:    // 属性string name {"None"};double balance {0.0};public:// 方法bool deposit(double amount){balance += amount;cout << name << "刚存入" << amount << "元,现在余额为" << balance << "元" << endl;return true;}; // 存款bool withdraw(double amount){if (balance >= amount){balance -= amount;cout << name << "刚取出" << amount << "元,现在余额为" << balance << "元" << endl;return true;} else {cout << name << "余额不足,取款失败" << endl;return false;}}; // 取款
};int main()
{Account jobs_account;// jobs_account.name = "Jobs";// jobs_account.balance = 1000.0;// cout << jobs_account.name << "的余额为" << jobs_account.balance << "元" << endl;jobs_account.deposit(500.0);return 0;
}
1.3 实现成员⽅法

在类中定义成员方法,适用于代码量较少的程序,

在这里插入图片描述

在类外面定义成员方法,适用于代码量较大的程序,

在这里插入图片描述

代码:

编译器无法区分 set_name 函数是类内的函数还是其他函数,所以在 set_name 前面添加类名::,表示这是类的成员函数

#include <iostream>
#include <string>
#include <vector>using namespace std;class Account
{
private:// 属性string name {"None"};double balance {0.0};public:// 方法// 设置余额void set_balance(double amount){balance = amount;};// 获取余额double get_balance(){return balance;};// 设置名称void set_name(string name);// 获取名称string get_name();// 存款bool deposit(double amount);// 取款bool withdraw(double amount);
};void Account::set_name(string name){this->name = name; // this指针指向当前对象
}
string Account::get_name(){return name;
}
bool Account::deposit(double amount){balance += amount;cout << name << "刚存入" << amount << "元,现在余额为" << balance << "元" << endl;return true;
}
bool Account::withdraw(double amount){if (balance >= amount){balance -= amount;cout << name << "刚取出" << amount << "元,现在余额为" << balance << "元" << endl;return true;} else {cout << name << "余额不足,取款失败" << endl;return false;}
}int main()
{Account alice_account;alice_account.set_name("Alice's account"); // 设置名称alice_account.set_balance(1000.0); // 设置余额cout << alice_account.get_name() << "的余额为" << alice_account.get_balance() << "元" << endl;alice_account.deposit(200.0);alice_account.withdraw(500.0);alice_account.withdraw(1500.0);return 0;
}

上面的代码看着比较繁杂,我们可以用头文件和源文件编写。
为了防止头文件被多次导入造成一些冲突,一般添加如下语句,关于头文件被多次导入造成一些冲突可参考这个链接:CSDN链接,例如创建 Account.h 头文件:

#ifndef ACCOUNT_H
#define ACCOUNT_H
#endif // ACCOUNT_H

整个 Account.h 头文件代码如下,一般不在头文件写 using namespace std;,一般显示地使用 std:string

#ifndef ACCOUNT_H
#define ACCOUNT_H
#include <string>class Account
{
private:// 属性std::string name {"None"};double balance {0.0};public:// 方法// 设置余额void set_balance(double amount){balance = amount;};// 获取余额double get_balance(){return balance;};// 设置名称void set_name(std::string name);// 获取名称std::string get_name();// 存款bool deposit(double amount);// 取款bool withdraw(double amount);
};#endif // ACCOUNT_H

然后再根据头文件编写类的成员方法的定义,因为在源文件引入了头文件#include "Account.h",所以不需要再写 #include <string>,这里也是显示地引入 std::coutstd::endl

#include "Account.h"
#include <iostream>void Account::set_name(std::string name){this->name = name; // this指针指向当前对象
}
std::string Account::get_name(){return name;
}
bool Account::deposit(double amount){balance += amount;std::cout << name << "刚存入" << amount << "元,现在余额为" << balance << "元" << std::endl;return true;
}
bool Account::withdraw(double amount){if (balance >= amount){balance -= amount;std::cout << name << "刚取出" << amount << "元,现在余额为" << balance << "元" << std::endl;return true;} else {std::cout << name << "余额不足,取款失败" << std::endl;return false;}
}

最后是程序的 main.cpp 文件,直接编译 main.cpp 即可,

#include <iostream>
#include <string>
#include <vector>
#include "Account.h" // 引入头文件using namespace std;int main()
{Account alice_account;alice_account.set_name("Alice's account"); // 设置名称alice_account.set_balance(1000.0); // 设置余额cout << alice_account.get_name() << "的余额为" << alice_account.get_balance() << "元" << endl;alice_account.deposit(200.0);alice_account.withdraw(500.0);alice_account.withdraw(1500.0);return 0;
}
1.4 构造函数(constructor)和 析构函数(destructor)
1.4.1 构造函数(constructor)

• 特殊的成员⽅法
对象创建的时候⾃动调⽤
• 适⽤于实例参数初始化
函数名和类的名称⼀致
• ⽆需设置返回类型
可以被重载(overload)

1.4.2 析构函数(destructor)

• 特殊的成员⽅法
• 函数名和类的名称⼀致,前⾯跟着⼀个~波浪符号
对象销毁的时候⾃动调⽤
• 没有参数,没有返回类型
• 只有⼀个析构函数(不能重载)
适⽤于释放内存等资源

如果不手动创建构造函数和析构函数,那么C++会自动帮助创建构造函数和析构函数,只不过都是空的,

构造函数(constructor)和析构函数(destructor):

在这里插入图片描述

构造函数在栈上创建,当程序运行结束时,他们各自的析构函数会被调用,所以会调用4次析构函数,

在这里插入图片描述

代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:// 属性std::string name {"account"};double balance {0.0};
public:void setName(string name){ this->name = name; }; // 设置名称// 构造函数Account(){cout << "没有参数的构造函数被调用" << endl;};Account(std::string name){cout << "带string name参数的构造函数被调用" << endl;};Account(double balance){ cout << "带double balance参数的构造函数被调用" << endl;};Account(string name, double balance){ cout << "带string name和double balance参数的构造函数被调用" << endl;};// 析构函数~Account(){ cout << name << " 的析构函数被调用" << endl;};
};int main()
{// 用{}表示作用域,{}内的程序运行后会调用析构函数{Account alice_account;alice_account.setName("Alice's account"); // 设置名称}// 出栈:后入先出{Account jobs_account;jobs_account.setName("Jobs's account"); Account bill_account("Bill's account");bill_account.setName("Bill's account"); Account steve_account(1000.0);steve_account.setName("Steve's account"); }Account *mark_account = new Account("Mark's account", 1000.0);mark_account->setName("Mark's account");delete mark_account;return 0;
}

输出:

没有参数的构造函数被调用
Alice's account 的析构函数被调用
没有参数的构造函数被调用
带string name参数的构造函数被调用
带double balance参数的构造函数被调用
Steve's account 的析构函数被调用
Bill's account 的析构函数被调用
Jobs's account 的析构函数被调用
带string name和double balance参数的构造函数被调用
Mark's account 的析构函数被调用

构造函数初始化列表:

:name {name} 中,冒号后面的 name 类成员属性的 name,{} 里面的 name 是函数的形参 name,

在这里插入图片描述

代码1:

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:// 属性std::string name {"account"};double balance {0.0};
public:// 打印信息void printInfo();// 构造函数,初始化参数Account(string name, double balance);};void Account::printInfo(){cout << "name: " << name << ", balance: " << balance << endl;
}
// 构造函数内部初始化参数
Account::Account(string name, double balance){this->name = name;this->balance = balance;
}int main()
{Account *mark_account = new Account("Mark's account", 1000.0);mark_account->printInfo(); // 打印信息delete mark_account;return 0;
}

输出:

name: Mark's account, balance: 1000

代码2:

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:// 属性std::string name {"account"};double balance {0.0};
public:// 打印信息void printInfo();// 构造函数,初始化参数Account();Account(string name);Account(string name, double balance);};void Account::printInfo(){cout << "name: " << name << ", balance: " << balance << endl;
}// 构造函数内部初始化参数
// Account::Account(){
//     name = "None";
//     balance = 0.0;
// }
// Account ::Account(string name){
//     this->name = name;
//     balance = 0.0;
// }
// Account::Account(string name, double balance){
//     this->name = name;
//     this->balance = balance;
// }// 构造函数初始化列表
Account::Account():name{"none"}, balance{0.0}{}
Account::Account(string name):name{name}, balance{0.0}{}Account::Account(string name, double balance):name{name}, balance{balance}{}int main()
{Account alice_account;alice_account.printInfo(); // 打印信息Account jobs_account {"Jobs's account"};jobs_account.printInfo(); Account bill_account {"Bill's account", 1000.0};bill_account.printInfo(); return 0;
}

输出:

name: none, balance: 0
name: Jobs's account, balance: 0
name: Bill's account, balance: 1000
1.5 代理构造函数(delegating constructor)

• 重载的构造函数很相似
• 冗余的代码可能会导致错误
• C++ 允许使⽤代理构造函数
------>• 在⼀个构造函数初始化列表中调⽤另⼀个构造函数

代码: 建议使用 debug 查看程序运行过程

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:// 属性std::string name {"account"};double balance {0.0};
public:// 打印信息void printInfo();// 构造函数,初始化参数Account();Account(string name);Account(string name, double balance);};void Account::printInfo(){cout << "name: " << name << ", balance: " << balance << endl;
}// 构造函数初始化列表
Account::Account():Account {"none",0}{}
Account::Account(string name):Account {name, 0}{}Account::Account(string name, double balance):name{name}, balance{balance}{}int main()
{Account alice_account;alice_account.printInfo(); // 打印信息Account jobs_account {"Jobs's account"};jobs_account.printInfo(); Account bill_account {"Bill's account", 1000.0};bill_account.printInfo(); return 0;
}

输出:

name: none, balance: 0
name: Jobs's account, balance: 0
name: Bill's account, balance: 1000
1.6 拷⻉构造函数(copy constructor)

• 当对象被拷⻉时,C++必须从已存在的对象复制出⼀个新的对象
• 何时使⽤拷⻉构造函数?
------->• 以值传递⽅式传递对象给函数(作参数)
------->• 函数以值⽅式返回对象
------->• 使⽤已存在的对象复制新的对象
• 如果不提供⾃⼰写的copy constructor,编译器会⾃动⽣成⼀个(可能不符合要求),如果是指针,拷贝的是地址,所以编译器自动生成的拷贝构造函数是浅拷贝

A、拷⻉构造函数——值传递

在这里插入图片描述

B、拷⻉构造函数——以值⽅式返回

以值⽅式返回拷⻉构造函数返回的 an_account 副本

在这里插入图片描述

C、拷⻉构造函数——使⽤已存在的对象复制新的对象

在这里插入图片描述

D、拷⻉构造函数的声明

首先拷⻉构造函数也是构造函数,所以函数的名称和类的名称一样,函数的参数列表是使用引用的方式传递的,

在这里插入图片描述

在这里插入图片描述

代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:// 属性string name {"account"};double balance {0.0};
public:string getName() {return name;} // 获取namedouble getBalance() {return balance;} // 获取balance// 构造函数Account(string name = "none", double balance = 0.0);// 析构函数~Account();// 拷贝构造函数Account(const Account &source);
};Account::Account(string name, double balance):name {name}, balance {balance}{cout << "2个参数的构造函数被调用,name:" << name << endl;}Account::~Account()
{cout << "析构函数被调用,name:" << name << endl;
}// 拷贝构造函数:根据已存在对象的属性来更新新对象的属性(name,balance)
Account::Account(const Account &source):name {source.name}, balance {source.balance} // 初始化列表{cout << "拷贝构造函数被调用,是" << source.name << "的拷贝" << endl;}
// 打印账户信息
void printAccountInfo(Account acc)
{cout << acc.getName() << "的余额是:" << acc.getBalance() << endl;
}
int main()
{// 1.值传递的方式给函数传递参数// Account alice_account;// printAccountInfo(alice_account);// 2.基于已存在的对象创建新的对象Account alice_account {"Alice's account", 1000.0};Account new_account {alice_account}; // 拷贝构造函数被调用return 0;
}

输出:

2个参数的构造函数被调用,name:Alice's account
拷贝构造函数被调用,是Alice's account的拷贝
析构函数被调用,name:Alice's account
析构函数被调用,name:Alice's account
1.7 浅拷贝(shallow copy)和深拷贝(deep copy)

• 如果不提供⾃⼰写的copy constructor,编译器会⽣成默认的
------>• 将⽬标对象的值逐个拷⻉过来;
------>• 如果是指针,拷⻉的是值(指向的地址),⽽不是指向的对象,称为浅拷贝
------>• 在析构函数中释放内存时,其他对象中的指针可能还在指向被释放的资源,在析构函数释放内存资源时可能会报错,例如下面的代码,如果使用编译器默认的拷贝构造函数,在进行析构函数释放内存资源时可能会报错

代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:// 属性string name {"account"};double *balance {nullptr};
public:double get_balance() {return *balance;}; // 获取余额string get_name() {return name;}; // 获取名字// 构造函数Account(string name = "none", double balance = 0.0); // 有默认参数的构造函数// 拷贝构造函数Account(const Account &source);// 析构函数~Account();};
Account::Account(string name, double balance){this->name = name;this->balance = new double {balance}; // 堆上分配内存cout << "2个参数的构造函数被调用,name: " << name << endl;}
// 拷贝构造函数    
Account::Account(const Account &source):Account {source.name, *source.balance} // 代理构造函数{cout << "拷贝构造函数被调用,是" << source.name << "的拷贝" << endl;} Account::~Account(){if (balance != nullptr)delete balance; // 释放内存cout << "析构函数被调用,name: " << name << endl;
}int main()
{// 演示浅拷贝和深拷贝Account alice_account {"Alice", 1000.0};Account new_account {alice_account}; // 拷贝构造函数被调用// cout << new_account.get_balance() << endl; // 1000.0return 0;
}

如果使用编译器默认的拷贝构造函数,在进行 alice_account 析构函数释放内存时会报错,如下图,如果使用自己写的拷贝构造函数就不会报错,

在这里插入图片描述

1.7.1 浅拷⻉(shallow copy)

如下图,alice_account 浅拷贝到 new_account,编译器会默认创建一个拷贝构造函数,它是逐个元素按值拷贝的如果是指针,则是拷贝的地址。当调用析构函数的时候,由于后进先出的原则,new_account 上的地址被释放后,alice_account 的地址也会被释放,但地址已经被释放,所以会造成堆空间重复释放的问题,导致程序报错,

在这里插入图片描述

编译器默认生成的拷贝构造函数如下:

在这里插入图片描述

1.7.2 深拷⻉(deep copy)

在函数内部,在堆上分配一个新的 double 类型的内存空间,初始化为1000,并且把新的内存空间给1000,

在这里插入图片描述

代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:// 属性string name {"account"};double *balance {nullptr};
public:double get_balance() {return *balance;}; // 获取余额string get_name() {return name;}; // 获取名字// 构造函数Account(string name = "none", double balance = 0.0); // 有默认参数的构造函数// 拷贝构造函数Account(const Account &source);// 析构函数~Account();};
Account::Account(string name, double balance){this->name = name;this->balance = new double {balance}; // 堆上分配内存cout << "2个参数的构造函数被调用,name: " << name << endl;}
// 拷贝构造函数    
Account::Account(const Account &source):Account {source.name, *source.balance} // 代理构造函数{cout << "拷贝构造函数被调用,是" << source.name << "的拷贝" << endl;} Account::~Account(){if (balance != nullptr)delete balance; // 释放内存cout << "析构函数被调用,name: " << name << endl;
}int main()
{// 演示浅拷贝和深拷贝Account alice_account {"Alice", 1000.0};Account new_account {alice_account}; // 拷贝构造函数被调用// cout << new_account.get_balance() << endl; // 1000.0return 0;
}
1.8 在类中使⽤const

• 常函数
------->• 函数名称后加const
------->• 函数体内不可以修改类成员属性
• 常对象
------->• 声明对象时前⾯加const
------->• 不可以修改常对象的成员属性
------->• 不能调用普通的成员方法,只能调⽤常函数

代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:double balance {0.0};public:string name {"account"};void set_new_name(string new_name) const{ // 修改名字// name = new_name;}string get_name() const{ // 获取名字return name;}// 构造函数Account(string name = "none", double balance = 0.0);~Account();
};Account::Account(string name, double balance): balance{balance} ,name{name}{cout << "构造函数" << endl;
}Account::~Account()
{cout << "析构函数" << endl;
}int main()
{// 常函数// Account alice_account {"Alice", 1000.0};// alice_account.set_new_name("Alice2"); // 修改名字// cout << alice_account.get_name() << endl; // Alice2// 常对象const Account bob_account {"Bob", 2000.0};// bob_account.name = "Bob2"; // 修改名字cout << bob_account.get_name() << endl; // Bob2return 0;
}
1.9 在类中使⽤static

• 静态成员变量
------->• 所有对象共有同⼀份数据(数据共享)
------->• 在类中声明,类外初始化
• 静态成员函数
------->• 所有对象共享同⼀个函数
------->• 只能访问静态成员变量

在这里插入图片描述

代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Account
{
private:// 属性string name {"account"};double balance {0.0};static int num_accounts;
public:static int get_num_accounts();Account(string name, double balance);~Account();
};int Account::num_accounts {0};Account::Account(string name, double balance):name{name}, balance{balance}{num_accounts++;}Account::~Account()
{num_accounts--;
}int Account::get_num_accounts() // 不需要使用static关键字
{// 静态成员方法只能访问静态成员变量// name = "test";return num_accounts;
}
int main()
{cout << Account::get_num_accounts() << endl;Account alice_account {"Alice's account", 1000.0};cout << alice_account.get_num_accounts() << endl;Account bob_account {"Bob's account", 2000.0};cout << Account::get_num_accounts() << endl;{Account test_account {"test", 100.0};cout << Account::get_num_accounts() << endl;}cout << Account::get_num_accounts() << endl;return 0;
}
1.10 struct 和 class区别

区别在于 class 成员权限默认是 private,而 struct 的成员权限默认是 public,

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/122474.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础 多线程

1.多线程创建方式1&#xff0c;继承Thread类&#xff1a; 2.多线程创建方式2&#xff1a; 匿名内部类写法 package thread;public class ThreadTest {public static void main(String[] args) {Runnable runnable new Runnable() {Overridepublic void run() {for (int i 0…

笔记本电脑的摄像头找不到黑屏解决办法

这种问题一般来说就是缺少驱动&#xff0c;就要下载驱动。 问题&#xff1a; 解决办法&#xff1a; 1.进入联想官网下载驱动 网站&#xff1a;https://newsupport.lenovo.com.cn/driveDownloads_index.html?v9d9bc7ad5023ef3c3d5e3cf386e2f187 2.下载主机编号检测工具 3.下…

虚幻中的网络概述一

前置&#xff1a;在学习完turbo强大佬的多人fps之后发觉自己在虚幻网络方面还有许多基础知识不太清楚&#xff0c;结合安宁Ken大佬与虚幻官方文档进行补足。 补充&#xff1a;官方文档中的描述挺好的&#xff0c;自己只算是搬运和将两者结合加强理解。 学习虚幻中的网络先从虚…

【Docker】Python Flask + Redis 练习

一、构建flask镜像 1.准备文件 创建app.py,内容如下 from flask import Flask from redis import Redis app Flask(__name__) redis Redis(hostos.environ.get(REDIS_HOST,127.0.0.1),port6379)app.route(/) def hello():redis.incr(hits)return f"Hello Container W…

串行原理编程,中文编程工具中的串行构件,串行连接操作简单

串行通信原理编程&#xff0c;中文编程工具中的串行通信构件&#xff0c;串行通信连接设置简单 编程系统化课程总目录及明细&#xff0c;点击进入了解详情。https://blog.csdn.net/qq_29129627/article/details/134073098?spm1001.2014.3001.5502 串行端口 是串行的基础&#…

【C++】类与对象 第二篇(构造函数,析构函数,拷贝构造,赋值重载)

目录 类的6个默认成员函数 初始化和清理 1.构造函数 2.析构函数 3.共同点 拷贝复制 1.拷贝构造 使用细节 2.赋值重载 运算符重载 < < > > ! 连续赋值 C入门 第一篇(C关键字&#xff0c; 命名空间&#xff0c;C输入&输出)-CSDN博客 C入门 第二篇( 引…

【开源】基于SpringBoot的海南旅游景点推荐系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四、核心代码4.1 随机景点推荐4.2 景点评价4.3 协同推荐算法4.4 网站登录4.5 查询景点美食 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的海南旅游推荐系统&#xff…

2017年上半年上午易错题(软件设计师考试)

CPU 执行算术运算或者逻辑运算时&#xff0c;常将源操作数和结果暂存在&#xff08; &#xff09;中。 A &#xff0e; 程序计数器 (PC) B. 累加器 (AC) C. 指令寄存器 (IR) D. 地址寄存器 (AR) 某系统由下图所示的冗余部件构成。若每个部件的千小时可靠度都为 R &…

如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样,蓝牙接近了电脑,电脑自动解锁无需输入开机密码

环境&#xff1a; Win10 专业版 远程解锁 蓝牙解锁小程序 问题描述&#xff1a; 如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样&#xff0c;蓝牙接近了电脑&#xff0c;电脑自动解锁无需输入开机密码 手机不需要拿出来&#xff0c;在口袋里就可以自动解锁&#xff…

C#,数值计算——分类与推理,基座向量机的 Svmgenkernel的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public abstract class Svmgenkernel { public int m { get; set; } public int kcalls { get; set; } public double[,] ker { get; set; } public double[] y { get; set…

机器学习-特征选择:如何使用互信息特征选择挑选出最佳特征?

一、引言 特征选择在机器学习中扮演着至关重要的角色&#xff0c;它可以帮助我们从大量的特征中挑选出对目标变量具有最大预测能力的特征。互信息特征选择是一种常用的特征选择方法&#xff0c;它通过计算特征与目标变量之间的互信息来评估特征的重要性。 互信息是信息论中的一…

Csdn文章编写参考案例

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

cosover是什么?crossover23又是什么软件

cosover是篮球里的过人技巧。 1.crossover在篮球中的本意是交叉步和急速交叉步。crossover 是篮球术语&#xff0c;有胯下运球、双手交替运球&#xff0c;交叉步过人、急速大幅度变向等之意。 2.在NBA里是指包括胯下运球、变向、插花在内的过人的技巧。 NBA有很多著名的Cross…

Linux进程等待

一、进程等待是什么&#xff1f; 通过系统调用wait/waitpid&#xff0c;来对子进程进行状态检验与回收的工作。 二、为什么要有进程等待 1、子进程退出&#xff0c;父进程如果不管不顾&#xff0c;就可能造成‘僵尸进程’的问题&#xff0c;进而造成内存泄漏。 另外&#xf…

数据库分库分表的原则

目录 1、数据库分库分表是什么 2、为什么要对数据库分库分表 3、何时选择分库分表 4、⭐分库分表遵循的原则 5、分库分表的方式 6、数据存放在表和库中的规则&#xff08;算法&#xff09; 7、分库分表的架构模式 8、分库分表的问题 小结 1、数据库分库分表是什么 数…

不一样的网络协议-------KCP协议

1、kcp 的协议特点 1.1、RTO 不翻倍 RTO(Retransmission TimeOut)&#xff0c;重传超时时间。tcp x 2&#xff0c;kcp x 1.5&#xff0c;提高传输速度 1.2、选择重传 TCP丢包时会全部重传从该包开始以后的数据&#xff0c;而KCP选择性重传&#xff0c;只重传真正丢失的数据包…

基于单片机16位智能抢答器设计

**单片机设计介绍&#xff0c;1645【毕设课设】基于单片机16位智能抢答器设计&#xff08;裁判功能、LCD数码管显示&#xff09;汇编 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序程序文档 六、 文章目录 一 概要 基于单片机16位智能抢答器设计&#x…

json格式存储b64编码的rgb raw数据

1.rgb raw数据准备 利用python将jpg里面的rgb raw数据提取出来。 import cv2# 读取 JPG 图像 image_path 1.jpg image cv2.imread(image_path)#imread读出来的顺序是BGR print("image shape:",image.shape)# 将图像由BGR转换为 RGB 数据 rgb_data cv2.cvtColor(im…

C++单调向量算法应用:所有子数组中不平衡数字之和

涉及知识点 单调向量 题目 一个长度为 n 下标从 0 开始的整数数组 arr 的 不平衡数字 定义为&#xff0c;在 sarr sorted(arr) 数组中&#xff0c;满足以下条件的下标数目&#xff1a; 0 < i < n - 1 &#xff0c;和 sarr[i1] - sarr[i] > 1 这里&#xff0c;sort…

vivado窗口使用与分析2-IDE 中的逻辑分析

逻辑分析 包括 &#xff1a; • “ Netlist ”窗口 • “ Hierarchy ”窗口 • “ Schematic ”窗口 1、 “ Netlist ”窗口 “ Netlist ” &#xff08; 网表 &#xff09; 窗口显示了网表中由综合工具所处理的设计层级。 根据综合设置 &#xff0c; 网表层级与原始 RT…