类和对象(提高)

news2025/2/23 22:44:10

类和对象(提高)

1、定义一个类 关键字class

在这里插入图片描述

6 class Data1
7 {
8 //类中 默认为私有
9 private:
10 int a;//不要给类中成员 初始化
11 protected://保护
12 int b;
13 public://公共
14 int c;
15 //在类的内部 不存在权限之分
16 void showData(void)
17 {
18 cout<<a<<" "<<b<<" "<<c<<endl;
19 }
20 };

2、成员函数在类外实现

class Student
{
private:
    int age;
public:
    void setAge(int a);
    void getAge(void);
};


void Student::setAge(int a)
{
    age=a;
}

void Student::getAge()
{
    cout<<age<<endl;
}

3、类在其他文件实现

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

头文件定义类, cpp实现类的成员函数

eg:student.h中

#ifndef STUDENT_H
#define STUDENT_H


class Student
{
private:
    int age;
public:
    void setAge(int a);
    void getAge(void);
};

#endif // STUDENT_H

student.cpp中

#include "student.h" //引入头文件
#include<iostream>
using namespace std;


void Student::setAge(int a)
{
    age=a;
}

void Student::getAge()
{
    cout<<age<<endl;
}

main.cpp实现student类

#include <iostream>
#include <cstring>
#include"student.h"
using namespace std;


int main(){
Student stu1;
stu1.setAge(18);
stu1.getAge();

return 0;
}

构造函数

1、如果用户不提供构造函数 编译器会自动 提供一个无参的空的构造函数。
2、如果用户提供构造函数 编译器会自动 屏蔽默认无参的构造

 class Data
 {
int mA;
 public:
Data()
 {
 mA = 0;
 cout<<"无参构造函数"<<endl;
}
 Data(int a)
{
 mA = a;
 cout<<"有参构造函数"<<endl;
 }
};
void test01()
 {
 //隐式调用无参构造(推荐)
 Data ob1;

 //显示调用无参构造
 Data ob2=Data();

 //隐式调用有参构造(推荐)
 Data ob3(10);

 //显示调用有参构造
 Data ob4=Data(20);

 //如果构造函数只有一个参数 可能发生 构造函数的隐式转换(知道就行)
 Data ob5 = 30;//Data ob5(30);

 //匿名对象:当前语句结束 对象就要被释放
 Data();//调用无参
 Data(40);//调用有参

 cout<<ob4.mA<<endl;
 }

析构函数

当对象生命周期结束的时候 系统自动调用析构函数。
函数名和类名称相同,在函数名前加~,没有返回值类型,没有函数形参。(不能被重载)
先调用析构函数 再释放对象的空间。

class Data1
 {
 public:
   int mA;
 public:
 //无参构造函数
 Data1()
 {
 mA=0;
 cout<<"无参构造函数"<<endl;
 }


 //有参构造函数
 Data1(int a)
 {
 mA=a;
 cout<<"有参构造函数 mA="<<mA<<endl;
 }

 //析构函数
 ~Data1()
 {
 cout<<"析构函数 mA="<<mA<<endl;
 }
 };

一般情况下,空的析构函数就足够。但是如果一个类有指针成员,这个类必须 写析构函数,释放指针成员所指向空间。

#include <iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;

class Data1{
private:
    char *name;

public:
    Data1(char *str){
        name=(char *)calloc(1,strlen(str)+1);
        strcpy(name,str);
    }
    //释放指针空间
    ~Data1(){
        cout<<"析构函数 name="<<name<<endl;
        if(name!=NULL){
            free(name);
            name=NULL;
        }
    }



};

int main(int argc, char *argv[])
{
Data1("张三");

    return 0;
}

拷贝构造函数

拷贝构造:本质是构造函数
拷贝构造的调用时机:旧对象 初始化 新对象 才会调用拷贝构造。

#include <iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;

class Data1{



public:
    int numA;
//拷贝函数
Data1(const Data1 &ob){//ob就是旧对象的别名

    numA=ob.numA;//一旦实现 了拷贝构造 必须完成赋值动作
    cout<<"调用拷贝函数"<<endl;
}
Data1(int a){

    numA=a;
}

};

int main(int argc, char *argv[])
{
Data1 ob1=Data1(10);
Data1 ob2=ob1;
cout<<"ob2:numA="<<ob2.numA<<endl;

    return 0;
}

如果用户不提供拷贝构造 编译器会自动提供一个默认的拷贝构造(完成赋值动作–浅拷贝)

拷贝构造 和 无参构造 有参构造的关系:
如果用户定义了 拷贝构造或者有参构造 都会屏蔽无参构造。
如果用户定义了 无参构造或者有参构造 不会屏蔽拷贝构造

拷贝构造函数几种调用方式

1、旧对象给新对象初始化,调用拷贝构造

Data4 ob1(10);
Data4 ob2 = ob1;//调用拷贝构造

2、给对象取别名 不会调用拷贝构造

Data4 ob1(10);
Data4 &ob2 = ob1;//不会调用拷贝构造

3、普通对象作为函数参数 调用喊谁时 会发生拷贝构造

void fun1(Data1 ob){//Data1 ob=obA


    cout<<ob.numA<<endl;
}

int main(int argc, char *argv[])
{

    Data1 obA(10);
    fun1(obA);
    return 0;
}

4、函数返回值普通对象 (Visual Studio会发生拷贝构造)(Qtcreater,linux不会发生)Visual Studio会发生拷贝构造

在这里插入图片描述

深拷贝

1、默认的拷贝构造 都是浅拷贝。
2、如果类中没有指针成员, 不用实现拷贝构造和析构函数。
3、如果类中有指针成员, 必须实现析构函数释放指针成员指向的堆区空间,必须实现拷贝构造完成深拷贝动作。

#include <iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;

class Data1{


public:
    char *name;

//有参构造
Data1(char *n){
     name=(char *)calloc(1,strlen(n)+1);
     strcpy(name,n);
}

~Data1(){
    cout<<"析构函数 name="<<name<<endl;
if(name!=NULL){
    free(name);
    name=NULL;
}

}
//深拷贝
Data1(const Data1 &ob){
name=(char *)calloc(1,strlen(ob.name)+1);
strcpy(name,ob.name);
}


};


int main(int argc, char *argv[])
{

Data1 obA("hello world");
Data1 ob=obA;
    return 0;
}

初始化列表

成员对象:一个类的对象作为另一个类的成员
如果类中想调用成员对象的有参构造 必须使用初始化列表。

在这里插入图片描述

class DataA{
public :
    int a;
public:
    DataA(){
        cout<<"A的无参构造"<<endl;
    }
    DataA(int num){
        a=num;
        cout<<"A的有参构造"<<endl;
    }
    ~DataA(){
        cout<<"A的析构函数"<<endl;
    }
};


class DataB{
public:
    int b;
    DataA ob;
public:
    DataB(){
        cout<<"B的无参构造"<<endl;
    }
    DataB(int num,int numa)
    {
        b=num;
        ob.a=numa;
        cout<<"B的有参构造"<<endl;
    }
    ~DataB(){
        cout<<"B的析构函数"<<endl;
    }
};

int main(int argc, char *argv[])
{
    DataB ob(10,20);

    return 0;
}

打印结果:

A的无参构造
B的有参构造
B的析构函数
A的析构函数

类会自动调用成员对象的无参构造。
类想调用成员对象 有参构造 必须使用初始化列表。

使用初始化列表,调用成员对象的有参构造

   DataB(int num,int numa):ob(numa)//修改B的有参构造
    {
        b=num;
        cout<<"B的有参构造"<<endl;
    }
A的有参构造
B的有参构造
B的析构函数
A的析构函数

对象数组

对象数组:本质是数组 数组的每个元素是对象

class DataA{
public :
    int a;
public:
    DataA(){
        cout<<"A的无参构造"<<endl;
    }
    DataA(int num){
        a=num;
        cout<<"A的有参构造"<<endl;
    }
    ~DataA(){
        cout<<"A的析构函数"<<endl;
    }
};



int main(int argc, char *argv[])
{
    //对象数组 每个元素都会自动调用构造和析构函数
    //对象数组不会自动初始化 每个元素 调用无参构造
//   ataA array[5];

    //对象数组的初始化 必须显示使用有参构造 逐个元素初始化
    DataA array[5]={DataA(1),DataA(2),DataA(3),DataA(4),DataA(5)};
    int len=sizeof(array)/sizeof(array[0]);
    for(int i=0;i<len;i++){
        cout<<array[i].a<<" ";
    }
    cout<<endl;
    return 0;
}

A的有参构造
A的有参构造
A的有参构造
A的有参构造
A的有参构造
1 2 3 4 5
A的析构函数
A的析构函数
A的析构函数
A的析构函数
A的析构函数

explicit函数

explicit防止构造函数隐式转换

什么是隐式转换?

class DataA{
public :
    int a;
public:
    DataA(){
        cout<<"A的无参构造"<<endl;
    }
    DataA(int num){
        a=num;
        cout<<"A的有参构造"<<endl;
    }
    ~DataA(){
        cout<<"A的析构函数"<<endl;
    }
};



int main(int argc, char *argv[])
{

    DataA ob=10;//隐式转换 DataA ob=Data(10);
    
    return 0;
}

加上explicit关键字防止隐式转换【new和delete 堆区空间操作

class DataA{
public :
    int a;
public:
    DataA(){
        cout<<"A的无参构造"<<endl;
    }
    explicit DataA(int num){
        a=num;
        cout<<"A的有参构造"<<endl;
    }
    ~DataA(){
        cout<<"A的析构函数"<<endl;
    }
};



int main(int argc, char *argv[])
{

    DataA ob=10;//error
    return 0;
}

new和delete 堆区空间操作

1、new和delete操作基本类型的空间

int main(int argc, char *argv[])
{
    int *p=new int(5);

    cout<<"*p="<<*p<<endl;
    delete p;
    return 0;
}

区别:
new 不用强制类型转换(malloc返回的类型是(void *))
new在申请空间的时候可以 初始化空间内容

new 申请基本类型的数组

int main(int argc, char *argv[])
{
    int *p=new int[5]{1,2,3,4,5};
    for(int i=0;i<5;i++){
        cout<<p[i]<<endl;
    }
    delete []p;//delete 数组要加上[]
    return 0;
}

2、new和delete操作类

malloc不会调用构造函数 free不会调用析构函数
new 会调用构造函数 delete调用析构函数

class DataA{
public :
    int a;
public:
    DataA(){
        cout<<"A的无参构造"<<endl;
    }
    explicit DataA(int num){
        a=num;
        cout<<"A的有参构造"<<endl;
    }
    ~DataA(){
        cout<<"A的析构函数"<<endl;
    }
};


int main(int argc, char *argv[])
{
DataA *p1=new DataA();
DataA *p2=new DataA();
DataA *array=new DataA[5]{DataA(1),DataA(2),DataA(3),DataA(4),DataA(5)};

delete p1;//delete
delete p2;
delete[]array;//释放数组的空间
    return 0;
}

静态成员

类的对象 拥有独立的 普通成员数据。
static 修饰的成员 叫 静态成员

class Data
 {
 static int a;//静态成员数据
 static void func()//静态成员函数
 {

 }

①静态成员数据

static修饰的静态成员 属于类而不是对象。(所有对象共享 一份 静态成员数据)

在这里插入图片描述

static修饰的成员 定义类的时候 必须分配空间。
static修饰的静态成员数据 必须类中定义 类外初始化。

class DataA{
public :
    int a;
    static int b;
public:
    DataA(){
        cout<<"A的无参构造"<<endl;
    }
     DataA(int num){
        a=num;
        cout<<"A的有参构造"<<endl;
    }
};

int DataA::b=100;//类外初始化

int main(int argc, char *argv[])
{

   cout<<DataA::b<<endl;//100
   DataA *ob=new DataA();
   cout<<ob.b<<endl;//100
   ob.b=200;
     cout<<DataA::b<<endl;//200
    return 0;
}

静态成员数据统计对象个数

#include <iostream>

using namespace std;

class DataA{
public :
    int a;
    static int count;
public:
    //无参构造
    DataA(){
        count++;
    }
    //有参构造
    DataA(int num){
        a=num;
    count++;
    }
     //拷贝构造
     DataA(const DataA &ob){
         a=ob.a;
         count++;
     }
     //析构函数
     ~DataA(){
         count--;
     }
};

int DataA::count=0;//类外初始化

int main(int argc, char *argv[])
{
DataA oba;
DataA obb(10);
DataA obc=oba;
cout<<"对象个数为"<<DataA::count<<endl;
    return 0;
}

静态成员函数

静态成员函数 是属于类 而不是对象(所有对象共享)

1、静态成员函数可以直接通过类名称访问

2、静态成员函数内只能操作静态成员数据

单例模式

单例模式的类,只能实例化一个对象

1、构造函数私有化

2、定义一个私有的对象指针,保存唯一的实例地址

#include <iostream>

using namespace std;

class SingleTon{

    //构造函数私有化
private:
     SingleTon(){
       count=0;
       cout<<"构造"<<endl;
    }
     ~SingleTon(){
         cout<<"析构函数"<<endl;
     }
     SingleTon(const SingleTon &ob){
         count=0;
         cout<<"拷贝构造"<<endl;
     }
 private:
     static SingleTon *const p;
     int count;

public:
     static SingleTon *getSingleTon(void){

         return p;
     }
     void printStirng(char *str){
         count++;
         cout<<"当前第"<<count<<"次任务打印:"<<str<<endl;
     }

};
SingleTon *const SingleTon::p=new SingleTon;


int main(int argc, char *argv[])
{
  SingleTon *p=SingleTon::getSingleTon();
  p->printStirng("hello");
  
    SingleTon *p2=SingleTon::getSingleTon();
      p2->printStirng("hello");
    return 0;
}

类的存储结构

类的成员函数和静态变量不占类的内存空间

在这里插入图片描述

const修改成员函数为只读

#include <iostream>
#include<string>
#include<stdlib.h>
using namespace std;

class DataA{
public :
    int a;
    mutable int b;//mutable修饰的成员变量可以修改

public:
  void printString(void) const{//const修饰成员函数为只读
//      this->a=100;//在打印函数中修改成员变量   error

      cout<<"a="<<a<<endl;
      this->b=100;
      cout<<"b="<<b<<endl;
  }
  DataA(int a,int b){
      this->a=a;

      this->b=b;
  }
};


int main(int argc, char *argv[])
{
    DataA ob=DataA(10,20);
    ob.printString();
  return 0;
}

友元

1、普通全局函数作为类的友元

#include <iostream>
#include<string>

using namespace std;

class Room{
    friend void visit(Room &room);//friend关键字
private:
    string bedRoom;//卧室
public:
    string setingRoom;//客厅
public:
    //构造函数
    Room(string bedRoom,string setingRoom){
        this->bedRoom=bedRoom;
        this->setingRoom=setingRoom;
    }

};

//普通的全局函数
void visit(Room &room){
    cout<<"访问了"<<room.setingRoom<<endl;
    cout<<"访问了"<<room.bedRoom<<endl;
}


int main(int argc, char *argv[])
{
    Room room("张三卧室","张三客厅");
    visit(room);
  return 0;
}

2、类的某个成员函数 作为另一个类的友元

#include <iostream>
#include<string.h>

using namespace std;

class Room;//先声明


class goodGay{
public:
    void visit01(Room &room);//先在类中声明,类外实现(否则之前只声明了Room,并没有声明Room中的成员,所以访问不了)
    void visit02(Room &room);
};

class Room{

friend  void goodGay::visit02(Room &room);//将类中成员函数声明为友元
private:
    string bedRoom;//卧室
public:
    string setingRoom;//客厅
public:
    //构造函数
    Room(string bedRoom,string setingRoom){
        this->bedRoom=bedRoom;
        this->setingRoom=setingRoom;
    }

};

//类外实现
void goodGay::visit01(Room &room)
 {
 cout<<"李四访问了"<<room.setingRoom<<endl;

 }

 void goodGay::visit02(Room &room)
 {
 cout<<"好基友张八访问了"<<room.setingRoom<<endl;
 cout<<"好基友张八访问了"<<room.bedRoom<<endl;
 }



int main(int argc, char *argv[])
{
    Room room("张三卧室","张三客厅");
  goodGay ob;
  ob.visit01(room);
  ob.visit02(room);
  return 0;
}

3、 整个类作为友元

这个类的所有成员函数 都可以访问另一个类的私有数据

#include <iostream>
#include<string.h>

using namespace std;

class Room;//先声明


class goodGay{
public:
    void visit01(Room &room);//先在类中声明,类外实现(否则之前只声明了Room,并没有声明Room中的成员,所以访问不了)
    void visit02(Room &room);
};

class Room{

    friend class goodGay;

private:
    string bedRoom;//卧室
public:
    string setingRoom;//客厅
public:
    //构造函数
    Room(string bedRoom,string setingRoom){
        this->bedRoom=bedRoom;
        this->setingRoom=setingRoom;
    }

};


void goodGay::visit01(Room &room)
 {
 cout<<"李四访问了"<<room.setingRoom<<endl;
 }


 void goodGay::visit02(Room &room)
 {
 cout<<"好基友张八访问了"<<room.setingRoom<<endl;
 cout<<"好基友张八访问了"<<room.bedRoom<<endl;
 }

int main(int argc, char *argv[])
{
    Room room("张三卧室","张三客厅");
  goodGay ob;
  ob.visit01(room);
  ob.visit02(room);
  return 0;
}

注意
1.友元关系不能被继承。
2.友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友。
3.友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友

设计动态数组类

Array.h

#ifndef ARRAY_H
#define ARRAY_H
class Array{
private:
    int *arr;//存放首地址元素
    int capacity;//容量
    int size;//大小

public:
    Array();
    Array(int capacity);
    Array(const Array &ob);
    ~Array();

    int getCapacity() const;//get容量
    int getSize() const;//getSize
    void printArray(void);//打印数组
    void pushBack(int elem);//从尾部插入数据
    void popBack(void);//删除尾部元素
    int &at(int pos);//获取元素,并返回引用类型
   };



#endif // ARRAY_H

array.cpp

#include "array.h"
#include "string.h"
#include <iostream>
using namespace std;
Array::Array(){
    capacity=5;
    size=0;
    arr=new int[capacity];
    memset(arr,0,sizeof(int)*capacity);

}
Array::Array(const Array &ob){
    capacity=ob.capacity;
    size=ob.size;
    arr=new int[capacity];
    memcpy(arr,ob.arr,sizeof(int)*capacity);

}
Array::~Array(){
    if(arr!=NULL){
        delete[]arr;
        arr=NULL;
    }
}
int Array::getCapacity()const{
    return capacity;
}
int Array::getSize()const{
    return size;
}
void Array::pushBack(int elem){
    if(size==capacity){
        int *temp=new int[2*capacity];
        memcpy(temp,arr,sizeof(int)*capacity);
        delete[]arr;
        arr=temp;
        capacity=2*capacity;

    }
    arr[size++]=elem;
    return;
}
void Array::popBack(){
    if(size==0){
        cout<<"容量为空"<<endl;

    }
    else{
        size--;
    }
    return;
}
int &Array::at(int pos){

    if(pos<0||pos>=size){
        cout<<"访问违法内存"<<endl;
        exit(-1);
    }
    return arr[pos];
}
void Array::printArray(void){
    for(int i=0;i<size;i++){
        cout<<arr[i]<<" ";

    }
    cout<<endl;
}

main.cpp

#include "array.h"
#include <iostream>
using namespace std;


int main(int argc, char *argv[])
{
Array array;
array.pushBack(10);
array.pushBack(20);
array.pushBack(30);
array.pushBack(40);
array.printArray();
array.at(2)=100;
array.printArray();
  return 0;
}

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

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

相关文章

远程登录WINDOWS10,提示你的凭据不工作

1&#xff1a;想通过远程桌面登录WINDOWS10输入用户名和密码后&#xff0c;出现下面的提示。 2&#xff1a;登录WINDOWS10&#xff0c;在运行中输入gpedit.msc 3&#xff1a;本地组策略编辑器窗口中&#xff0c;依次展开&#xff0c;计算机配置 ---> 管理模版---> 系统--…

海外注册 | 欧盟医疗器械法规下免除临床试验的条件与要求

在欧盟医疗器械法规&#xff08;MDR&#xff09;的严格监管下&#xff0c;植入性医疗器械和III类医疗器械通常需要进行临床试验来证明其安全性和性能。 然而&#xff0c;MDR也规定了一些特定情况下免除临床试验的可能性。以下是免除临床试验的条件和要求的详细说明&#xff1a…

“穿越时空的机械奇观:记里鼓车的历史与科技探秘“

在人类文明的发展历程中&#xff0c;科技的创新与进步不仅仅推动了社会的进步&#xff0c;也为我们留下了丰富的文化遗产。记里鼓车&#xff0c;作为一种古老的里程计量工具&#xff0c;其历史地位和技术成就在科技史上具有重要的意义。本文将详细介绍记里鼓车的起源、结构原理…

视频分析、目标检测的过去和未来:目标检测从入门到精通 ------ YOLOv8 到 多模态大模型处理视觉基础任务

文章大纲 计算机视觉项目的关键步骤目标检测入门视频分析项目最佳实践数据集构建数据准备:数据集标注规范与数据规模参考标注工具标注工具:目标检测yolo 极简标注工具综合标注工具:label-studio半自动标注工具:X-AnyLabeling目标检测与多模态哪些多模态模型可以做目标检测?…

顺序表--续(C语言详细版)

2.9 在指定位置之前插入数据 // 在指定位置之前插入数据 void SLInsert(SL* ps, int pos, SLDataType x); 步骤&#xff1a; ① 程序开始前&#xff0c;我们要断言一下&#xff0c;确保指针是有效的&#xff0c;不是NULL&#xff1b; ② 我们还要断言一下&#xff0c;指定的…

【大模型LLM面试合集】大语言模型基础_llm概念

1.llm概念 1.目前 主流的开源模型体系 有哪些&#xff1f; 目前主流的开源LLM&#xff08;语言模型&#xff09;模型体系包括以下几个&#xff1a; GPT&#xff08;Generative Pre-trained Transformer&#xff09;系列&#xff1a;由OpenAI发布的一系列基于Transformer架构…

64位Office API声明语句第120讲

跟我学VBA&#xff0c;我这里专注VBA, 授人以渔。我98年开始&#xff0c;从源码接触VBA已经20余年了&#xff0c;随着年龄的增长&#xff0c;越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友&#xff0c;都来学习VBA,利用VBA,起码可以提高…

JVM原理(十二):JVM虚拟机类加载过程

一个类型从被加载到虚拟机内存中开始&#xff0c;到卸载为止&#xff0c;它的整个生命周期将会经过 加载、验证、准备、解析、初始化、使用、卸载七个阶段。其中 验证、准备、解析三个部分统称为 连接 1. 加载 加载是整个类加载的一个过程。在加载阶段&#xff0c;Java虚拟机…

第25篇 滑动开关控制LED<三>

Q&#xff1a;如何创建流水灯汇编语言程序工程并运行呢&#xff1f; A&#xff1a;基本原理&#xff1a;与用单个SW控制单个对应LED点亮与熄灭一样&#xff0c;我们创建用SW控制流水灯状态。默认初始状态为4个连续的红色LED为一组&#xff08;每组之间隔4个熄灭的LED&#xff…

如何在网络抓取过程中绕过 CAPTCHA 和 reCAPTCHA?

什么是 CAPTCHA&#xff1f; CAPTCHA&#xff0c;全称为 “Completely Automated Public Turing test to tell Computers and Humans Apart”&#xff08;完全自动化的公共图灵测试以区分计算机和人类&#xff09;&#xff0c;是一种用于识别网站访问者是否为真实人的测试。 这…

绝区零国际服怎么下载 绝区零国际服下载教程

绝区零即将上线&#xff0c;每位玩家都能在这里开启全新的时空冒险之旅&#xff0c;主要玩法分为以剧情和副本为主的核心玩法、以刷材料为主的养成副本&#xff0c;以及日常任务为主&#xff0c;在以往的手游中&#xff0c;玩家进入某项玩法只需要从游戏界面调取菜单即可&#…

Django 一对一关系

作用&#xff1a; 两个数据库表建立外键关系当外键表的数据被删除时&#xff0c;主表的数据也会一并删除。 1&#xff0c;添加表模型 Test/app8/views.pyfrom django.db import modelsclass User(models.Model):username models.CharField(max_length50, uniqueTrue)email …

程序员AI提效案例:统计B站课程耗时情况

文章目录 一&#xff0c;时长统计需求二&#xff0c;一波三折三&#xff0c;终极方案 AIJava总结 今天为了写一篇博客&#xff0c;这篇博客介绍了B站的一个Java项目&#xff0c;这个项目分为三个阶段&#xff1a; 初级篇高级篇运维篇 一&#xff0c;时长统计需求 我想根据每个…

软件测试中安全测试包含内容及安全测试怎么测

一、软件测试安全测试包含哪些 1. 漏洞扫描 漏洞扫描是软件测试安全测试的基础&#xff0c;它用于检测应用程序和系统中存在的已知漏洞。安全测试工具如AppScan、OWASP ZAP和Nessus等可以对应用程序进行自动化扫描&#xff0c;发现可能存在的漏洞&#xff0c;如跨站点脚本&am…

大象机器人开源协作机械臂机械臂接入GPT4o大模型!

本文已经或者同济子豪兄作者授权对文章进行编辑和转载 引言 随着人工智能和机器人技术的快速发展&#xff0c;机械臂在工业、医疗和服务业等领域的应用越来越广泛。通过结合大模型和多模态AI&#xff0c;机械臂能够实现更加复杂和智能化的任务&#xff0c;提升了人机协作的效率…

CTO透露GPT-5内幕,OpenAI 以36亿美元收购数据库初创公司

目录 01 GPT-5 02 OpenAI收购Rockset 2.1 谁是Rockset&#xff1f; 2.2 OpenAI的目的是什么&#xff1f; 01 GPT-5 虽然GPT-4的视频通话功能尚未全面推广&#xff0c;但OpenAI的CTO已经对即将到来的GPT-5给出了新的暗示。 不久前&#xff0c;Mira回到母校达特茅斯工程学…

jdk动态代理-基于反射的动态代理

JDK动态代理的示例图&#xff0c;下图的绿色箭头表示实现的关系&#xff0c;白色虚线表示依赖关系&#xff0c;target表示被ProxyFactory的target成员表示代理类对象&#xff0c;由ProxyFactory传入的Object参数初始化&#xff0c;接着调用getProxyInstance函数利用反射来返回代…

DMA学习笔记

参考文章 https://blog.csdn.net/as480133937/article/details/104927922 DMA简介 DMA&#xff0c;全称Direct Memory Access&#xff0c;即直接存储器访问。DMAC 即 DMA 控制器&#xff0c;提供了一种硬件的数据传输方式&#xff0c;无需 CPU 的介入&#xff0c;可以处理外…

LangGraph进阶:手把手教你打造电影脚本AI

LangGraph是著名的大模型开发框架LangChain推出的用于构建基于复杂工作流的LLM应用的开发库。LangGraph把任务的节点与关系用Graph结构来定义以支持更多样更复杂的应用场景&#xff0c;特别是&#xff1a; 实现包含循环、迭代等复杂工作流的高级RAG范式 需要更灵活控制的Agent…