【c++基础】第二章 微观部分:面向对象之类的组成

news2024/9/23 17:24:13

第二章 微观部分:面向对象之类的组成

  • 函数
    • 构造函数
    • 析构函数
    • 拷贝构造函数
    • 运算符重载函数
    • ==封装一个字符串类==
  • 初始化列表
  • this指针
  • 常对象和常成员函数(方法)
  • 静态属性和静态成员函数
  • ==单例设计模式==

对象:属性和方法组成,是类的一个实例化

类(class):具有相同属性和方法,是对象的抽象

类的封装性:权限(public/private/protected)+属性+方法

在这里插入图片描述

在这里插入图片描述

类的大小(和结构体相似):

空类,1byte;类对象的大小与类中的非静态属性相关,类对象共享类中的成员函数的地址

练习:

#include <iostream>

using namespace std;

class rectangle{
    int wide;
    int length;
public:
    void setwide(int wide){
        this->wide=wide;
    }
    void setlength(int length){
        this->length=length;
    }

    int getArea(){
        return this->wide*this->length;
    }
};

rectangle& compair(rectangle& r1,rectangle& r2){
    return r1.getArea()>r2.getArea()?r1:r2;
}

int main()
{
    int wide=10;
    int length=20;
    rectangle *rect1=new rectangle();
    rect1->setwide(wide);
    rect1->setlength(length);
    cout << "rectangle's area1 = " << rect1->getArea() << endl;

    wide=20;
    length=30;
    rectangle rect2;
    rect2.setwide(wide);
    rect2.setlength(length);
    cout << "rectangle's area2 = " << rect2.getArea() << endl;

    cout << "---------------------------------------------------" << endl;
    cout << "较大的面积为:" << endl;
    cout << compair(*rect1,rect2).getArea() << endl;

    return 0;
}

函数

类中函数(类的骨架):

  • 构造函数
  • 析构函数
  • 可被构造函数
  • 运算符重载函数
  • 取值运算符
  • 长取值运算符

构造函数

没有任何返回值,函数名与类名相同,由编译器根据对象定义参数决定

  • 不存在,编译器生成一个无参的空构造
  • 存在,编译器不在生成
  • 意义:对类对象属性进行初始化类中get()/set()函数的升级
#include <iostream>

using namespace std;

class stu{
    string name;
    int age;
public:
    stu(){
        cout << "stu的无参构造" << endl;
    }
    stu(string name,int age){ 
        this->name=name;
        this->age=age;
        cout << "stu的有参构造" << endl;
    }
    void showInfo(){
        cout << "姓名:" << this->name << "  年龄:" << this->age << endl;
    }
};

int main()
{
    stu s1;
//    stu s1();//是一个函数声明,并非是无参函数的调用
    stu s2("yao",18);
    s2.showInfo();
    stu *s3=new stu("yaoliang",19);
    s3->showInfo();
    delete s3;
    return 0;
}

显示(explicit)调用和隐式(implicit expression) 调用

#include <iostream>

using namespace std;

class A{
    int a;
public:
    A(){
       cout << "i am is NULL structure" << endl;
    }
    A(int a){
        cout << "i am is single structure" << endl;
    }
    A(int a,int b){
        cout << "i am is more structure" << endl;
    }
    explicit A(int a,int b,int c){
        cout << "i am is more more structure" << endl;
    }
};

int main()
{
    cout << " explicit structure " << endl ;
    A a;
    A a1(1);
    A a2(1,2);
    A a3(1,2,3);
    cout << " implicit  expression strcture" << endl ;
    A a4 = 1;
    A a5 = {1,2};
//    A a6 = {1,2,3};//在类构造函数前加上explicit,无法隐式调用
    return 0;
}

析构函数

在这里插入图片描述

#include <iostream>

using namespace std;

class stu{
    string name;
    int age;
    int *p;
public:
    stu(string name,int age){
        this->name=name;
        this->age=age;
        this->p=new int[1024];
        cout << "stu structure" << endl;
    }
    ~stu(){
        delete []p;
        cout << "stu destruct" << endl;
    }
};

int main()
{
    stu s1("zhangsan",10);
    stu *s2 = new stu("yao",18);
    delete s2;
    return 0;
}

好处:避免内存泄漏,先清理资源,在销毁空间

拷贝构造函数

类中没有提供拷贝构造函数,当出现使用其他对象为本对象进行初始化时,编译器自动生成,以供调用

浅拷贝:

  • 优点:简单赋值,可以提高效率
  • 缺点:指针共享一块内存,析构后,内存被回收

在这里插入图片描述

#include <iostream>

using namespace std;

class stu{
    string _name;
    int _age;
    int *_score;
public:
    stu(string name,int age,int *score)
    {
        this->_name=name;
        this->_age=age;
        this->_score=new int[10] ();
        memcpy(this->_score,score,10);
//        this->_score=score;
        cout << "stu structure" << endl;
    }
    ~stu(){
        delete [] _score;
        cout << "stu destruct" << endl;
    }
    stu(const stu& other){
        this->_name=other._name;
        this->_age=other._age;
//        this->_p=other._p;
        //深拷贝
        this->_score=new int[10];
        memmove(this->_score,other._score,sizeof(int[10]));
        cout << "stu copy" <<endl;
    }
    void showInfo()const{
        cout << "姓名: " << this->_name ;
        cout << "年龄: " << this->_age ;
        cout << "成绩: " << this->_score[0] ;
        cout << endl;
    }

    int getAge()const{
        return this->_age;
    }
};

const stu& compair(const stu& s1,const stu& s2){
    return s1.getAge()>s2.getAge()?s2:s1;
}

//多拷贝3次
//stu compair(stu s1,stu s2){
//    return s1.getAge()>s2.getAge()?s2:s1;
//} 

int main()
{
    int score[10]={100,80,40};
    //显示调用
    stu s1("yaoliang",18,score);
    stu s2(s1);
    s2.showInfo();
    //隐式调用
    stu s3("minmin",17,score);
    stu s4=s3;
    s4.showInfo();

    cout << "-----------stu's age compair ,input small age imformation------------" << endl;
    compair(s2,s4).showInfo();
    return 0;
}

引用可以提高深拷贝的运行效率,使用常引用,保证实参安全

运算符重载函数

面向对象服务全局也可以定义,但类中优先存在深浅拷贝(针对=)

等号运算符重载函数,深拷贝要谨慎

stu& operator=(const stu& other){
    this->_name=other._name;
    this->_age=other._age;
    //判空,删除原空间,创建新空间
    if(this->_score!=nullptr){
    	delete []_score;
    } 
    this->_score=new int[10] ();
    memcpy(this->_score,other._score,10);
    cout << "stu equal operator overloading" <<endl;
    return *this;
}

测试代码:

#include <iostream>

using namespace std;

class stu{
    string _name;
    int _age;
    int *_score;
public:
    stu(string name,int age,int *score)
    {
        this->_name=name;
        this->_age=age;
        this->_score=new int[10] ();
        memcpy(this->_score,score,10);
//        this->_score=score;
        cout << "stu structure" << endl;
    }
    ~stu(){
        delete [] _score;
        cout << "stu destruct" << endl;
    }
    stu(const stu& other){
        this->_name=other._name;
        this->_age=other._age;
//        this->_p=other._p;
        //深拷贝
        this->_score=new int[10];
        memmove(this->_score,other._score,sizeof(int[10]));
        cout << "stu copy" <<endl;
    }
    //系统默认
    stu& operator=(const stu& other){
        this->_name=other._name;
        this->_age=other._age;
        //要必须小心
        if(this->_score!=nullptr){
            delete []_score;
        } 
        this->_score=new int[10] ();
        memcpy(this->_score,other._score,10);
        cout << "stu equal operator overloading" <<endl;
        return *this;
    }
    //自定义加法
    int operator+(const stu& other){
        return this->getAge()+other.getAge();
    }
    //自定义减法
    int operator-(const stu& other){
        cout << "class inside" << endl;
        return this->getAge()+other.getAge();
    }
    void showInfo()const{
        cout << "姓名: " << this->_name ;
        cout << "年龄: " << this->_age ;
        cout << "成绩: " << this->_score[0] ;
        cout << endl;
    }

    int getAge()const{
        return this->_age;
    }
};

const int operator-(const stu& s1,const stu& s2){
    cout << "class external" << endl;
    return s1.getAge()-s2.getAge();
}

const stu& compair(const stu& s1,const stu& s2){
    return s1.getAge()>s2.getAge()?s2:s1;
}

//stu compair(stu s1,stu s2){
//    return s1.getAge()>s2.getAge()?s2:s1;
//}

int main()
{
    int score[10]={100,80,40};
    //显示调用
    stu s1("yaoliang",18,score);
    stu s2(s1);
    s2.showInfo();
    //隐式调用
    stu s3("minmin",17,score);
    stu s4=s3;
    s4.showInfo();

    s3=s2;
    s3.operator=(s2);
    s3.showInfo();//系统自动创建了一个等号运算符重载
    cout << "---stu's age compair ,input small age imformation----" << endl;
    compair(s2,s4).showInfo();

    cout << "--using operator overloading (overall situation) ,stu age sub--" << endl;
    cout << s1-s4 << endl;
    cout << operator-(s1,s4) << endl;

    cout << "-----------using operator overloading ,stu age add------------" << endl;
    cout << s1+s4 << endl;

    return 0;
}

注意:

  • 在全局不可重载的运算符:=,->,[],()
  • 不能重载:.(.运算符),::(域运算符),.*(. *运算符),?:(三目运算符),(sizeof运算符),(#预处理运算符)

自增自减运算符

前自增

返回值 operator++()

后自增:

返回值 operator++(int)//亚元

#include <iostream>
#include <unistd.h>

using namespace std;

class Clock{
    int min;
    int sec;
public:
    Clock(int m,int s){
        this->min=m;
        this->sec=s;
    }

    Clock& operator++(){
        ++sec;
        if(0==sec%60){
            ++min;
            sec=0;
            if(0==min%60){
                this->min=0;
            }
        }
        return *this;
    }
    Clock& operator++(int){
        sec++;
        if(sec%60==0){
            min++;
            sec=0;
            if(min%60==0){
                this->min=0;
            }
        }
        return *this;
    }
    //Clock& operator++(int){
    //	  this->operator++();
    //    (*this).operator++();
    //    return ++*this;//三种效果一致
    //}
    
    void display(){
        cout << this->min << ":" << this->sec << endl;
    }
};

int main()
{
    Clock c(0,0);
    while(true){
        c++;
        c.display();
        sleep(1);
    }
    return 0;
}

封装一个字符串类

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

class MyString{
private:
    char* m_data;
public:
    //MyString无参空构造
    MyString(){
        this->m_data=new char[1];
        this->m_data[0]='\0';
    }
    //MyString有参构造:在c++中字符串常量的类型,一定是const char* 类型
    MyString(const char* c_str){
        int len=strlen(c_str);
        this->m_data=new char[len+1];
        memmove(this->m_data,c_str,len);
        this->m_data[len]='\0';
    }
    //MyString 的拷贝构造
    MyString(const MyString& other){
        int len=strlen(other.m_data);
        this->m_data=new char[len+1];
        memmove(this->m_data,other.m_data,len);
        this->m_data[len]='\0';
    }
    //=号运算符重载函数
    MyString& operator=(const MyString& other){
        if(this==&other){
            return  *this;
        }
        int len=strlen(other.m_data);
        if(nullptr!=this->m_data){
            delete [] m_data;
            this->m_data=new char[len+1];
        }else{
            this->m_data=new char[len+1];
        }
        memmove(this->m_data,other.m_data,len);
        this->m_data[len]='\0';
        return  *this;
    }

    //析构
    ~MyString(){
        delete []m_data;
        this->m_data=nullptr;
    }

    //查找下标元素
    char operator[](int index){
        if(index < 0 || index >= strlen(this->m_data)){
            cout << "cross the border" << endl;
        }
        return  this->m_data[index];
    }
    //加法运算
    MyString operator+(const MyString& other){
        int my_len=strlen(this->m_data);
        int other_len=strlen(other.m_data);

        char *temp=new char[my_len+other_len+1];
        memmove(temp,this->m_data,my_len);
        memmove(temp+my_len,other.m_data,other_len);
        temp[my_len+other_len]='\0';

        MyString temp_str=temp;
        delete [] temp;
        return temp_str;
    }
    char* getM_data()const{
        return this->m_data;
    }
};
ostream& operator << (ostream& cout,const MyString& other){
    cout << other.getM_data();
    return cout;
}

int main()
{
    MyString str;
    MyString str1("hello");
    MyString str2=str1;
    MyString str3="yao";
    MyString str4="liang";
    cout << str1.getM_data() << endl;
    cout << str1 << endl;
    cout << str2 << endl;
    cout << str1[2] << endl;
    cout << str3+str4 << endl;

    return 0;
}

初始化列表

const修饰的常属性(只读属性)的初始化方式。

在C++中const修饰的对象,必要初始化

类中构造函数的特殊语法(高效率):

类中构造函数的初始化列表早于构造函数,在对象开辟空间时,解决const问题

初始化列表语法:在类中构造函数后+:类中的属性(外部参数)

遵循原则:顺序初始化(忽略static修饰的属性)

#include <iostream>

using namespace std;

class Score{
    int score;
public:
    Score(int score){
        cout << this->score << endl;
    }
};

class stu{
    string _name;
    int _age=128;
    int _salary;
    string *_friend;
    Score _s=Score(100);
public:
    stu(string name,int age):_name(name),_age(age),_salary(10000),_friend(new string[10]{"sunsun"}),_s(Score(100))
    {
        cout << "stu的有参构造" << endl;
    }
    ~stu(){
        delete []_friend;
        cout << "stu destruct" << endl;
    }
    void showInfo(){
        cout << "姓名:" << this->_name << "  年龄:" << this->_age ;
        cout << "工资:" << this->_salary << " 朋友1:" << this->_friend[0] ;
        cout  << endl;

    }
};

int main()
{
    stu s1("yaoliang",18);
    s1.showInfo();
    Score s(10);
    return 0;
}

this指针

在c中的体现:

#include <stdio.h>

typedef void (*Pfunc_t)();

typedef struct Stu
{
    char *name;
    int age;
    Pfunc_t f;
}stu;

void showInfo(stu *const this){
    printf("姓名:%s,年龄:%d\n",this->name,this->age);
}

int main(int argc, const char *argv[])
{
    /*your code*/
    stu s={"yaoliang",20,showInfo};

    s.f(&s);
   return 0;
}

C++中this指针

  • 就是本对象的起始地址(const修饰的常地址)
  • 是隐藏(非静态)在成员函数最左侧的一个常变量形参

两种用法:

  • 区分属性名与形参名
  • 解引用,返回本对象
#include <iostream>

using namespace std;

class Stu{
    string name;
    int age;
public:
    //1.当成员函数中形参变量与类属性变量重名时,使用this加以区分
    Stu(string name,int age){
        this->name=name;
        this->age=age;
//        name=name;//error
//        age=age;//error
    }
    void showInfo(){
        cout << "姓名: " << this->name << " , 年龄: " << this->age << endl;
//        cout << "姓名: " << name << " , 年龄: " << age << endl;//error
    }
    //2.返回本对象  *this
    Stu& setName(string name){
        this->name=name;
        return *this;
    }
};

int main()
{
    Stu stu("yaoliang",18);
    stu.showInfo();
    stu.setName("liang").showInfo();
    return 0;
}

常对象和常成员函数(方法)

常对象,const修饰的对象

特性:

  • 只读,不可修改

  • 不能调用普通成员函数(有修改权限),只能调用常函数

常函数,const修饰的函数

特性:

  • 不修改函数类中的属性,只读
#include <iostream>

using namespace std;

class rectangle{
    int wide;
    int length;
public:
//    rectangle(int wide,int length){
//        this->wide=wide;
//        this->length=length;
//    }
    void setwide(int wide){
        this->wide=wide;
    }
    void setlength(int length){
        this->length=length;
    }

    int getArea()const{
        return this->wide*this->length;
    }
};

//更安全
const rectangle& compair(const rectangle& r1,const rectangle& r2){
    return r1.getArea()>r2.getArea()?r1:r2;
}

//rectangle& compair( rectangle& r1,rectangle& r2){
//    r1.setwide(10);
//    r1.setlength(100000);
//    return r1.getArea()>r2.getArea()?r1:r2;
//}

int main()
{
    int wide=10;
    int length=20;
    rectangle *rect1=new rectangle();
    rect1->setwide(wide);
    rect1->setlength(length);
    cout << "rectangle's area1 = " << rect1->getArea() << endl;

    wide=20;
    length=30;
    rectangle rect2;
    rect2.setwide(wide);
    rect2.setlength(length);
    cout << "rectangle's area2 = " << rect2.getArea() << endl;

    cout << "---------------------------------------------------" << endl;
    cout << "较大的面积为:" << endl;
    cout << compair(*rect1,rect2).getArea() << endl;

    return 0;
}

静态属性和静态成员函数

特点:

  • 静态属性**资源共享**

  • 静态属性隐藏于类域之中,可以通过域名+::(域名访问符)直接访问

  • 静态成员函数访问不到类中属性,原因:最左侧没有常变量形参this

  • 静态成员函数可以访问静态属性,与静态属性类似,不依赖于某个对象调用

  • static修饰

    • 修饰属性时,修饰的是属性的存储形式,需要在类外全局.cpp文件中定义:例:stu::count=0;
    • 修饰函数时,修饰的是级别,隐藏在本类的类域中,为全类服务,可以域名::方式直接调用
#include <iostream>

using namespace std;

class stu{
    string _name;
    const int _age=128;
    int _salary;
    string *_friend;
    static int count;
public:
    stu(string name,int age):_name(name),_age(age),_salary(10000),_friend(new string[10]{"sunsun"})
    {
        count++;
        cout << "stu的有参构造" << endl;
    }
    ~stu(){
        delete []_friend;
        cout << "stu destruct" << endl;
    }
    void showInfo(){
        cout << "姓名:" << this->_name << "  年龄:" << this->_age ;
        cout << "工资:" << this->_salary << " 朋友1:" << this->_friend[0] ;
        cout  << endl;
    }
    static int get_count(){
        return count;
    }
};

//需要在全局定义的原因:
//静态变量在声明时就需要开辟空间,而在类中不会开辟空间
int stu::count = 0;

int main()
{
    stu s1("yaoliang",18);
    s1.showInfo();
    cout << "count = "  << stu::get_count() << endl;//1
    return 0;
}

单例设计模式

一个类,在外部只能生成一个实例,最大限度的减小资源占用

以下为**饿汉式**:

  • 优点:线程安全
  • 缺点:占用一块堆上的资源
#include <iostream>

using namespace std;
class singleton{
private:
    //1.把类中的构造设置为私有
    singleton(){
        cout << "singleton的构造" << endl;
    }
    static singleton* my_instance;
public:
    //2.提供一个公有接口函数返回本对象的指针
    //3.公有接口不想依赖类对象的调用,是不是应该把该接口升级为static静态成员函数
    static singleton* getInstance(){
        //4.在类私有属性中定义一个静态的私有成员对象类型的属性指针,并把公有接口中返回出去
        return my_instance;
    }
};

//5.在类外完成对类中静态属性指针的初始化
singleton* singleton::my_instance=new singleton();

int main()
{
    singleton* s1=singleton::getInstance();
    singleton* s2=singleton::getInstance();
    singleton* s3=singleton::getInstance();

    cout << s1 << endl;
    cout << s2 << endl;
    cout << s3 << endl;
    return 0;
}

以下为**懒汉式**:

  • 优点:不用不占用资源
  • 缺点:
    • 生成死递归,所以懒汉不提供析构,只能自己创建
    • 不在使用全部申请的空间,线程不安全,所以要加智能锁
#include <iostream>
#include <mutex>
using namespace std;

//设置全局锁
mutex mtx;

class singleton{
private:
    //1.把类中的构造设置为私有
    singleton(){
        cout << "singleton的构造" << endl;
    }
    static singleton* my_instance;
public:
    //2.提供一个公有借口函数返回本对象的指针
    //3.公有接口不想依赖类对象的调用,是不是应该把该接口升级为static静态成员函数
    static singleton* getInstance(){
        //4.在类私有属性中定义一个静态的私有成员对象类型的属性指针,并把公有接口中返回出去
        //c++11智能锁类型(可被析构):
        lock_guard<mutex> lock(mtx);//c++11线程安全的懒汉式单例
        if(nullptr==my_instance){
            my_instance =new singleton();
        }
        return my_instance;
    }
    //懒汉式析构
    void destroy(){
        if(nullptr!=my_instance){
            delete my_instance;
            my_instance=nullptr;
        }
    }
    
    //析构
//    ~singleton(){
        delete my_instance;//生成死递归,所以懒汉不提供析构
//    }
};

//5.在类外完成对类中静态属性指针的初始化
singleton* singleton::my_instance=nullptr;

int main()
{
    singleton* s1=singleton::getInstance();
    singleton* s2=singleton::getInstance();
    singleton* s3=singleton::getInstance();

    cout << s1 << endl;
    cout << s2 << endl;
    cout << s3 << endl;
    return 0;
}

注意:类中的静态属性当其初始化时,可以调用类中的私有属性和方法

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

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

相关文章

Nature子刊 | 空间转录组技术及其发展方向

2022年10月《Nature Biotechnology》发表了一篇空间转录组&#xff08;ST&#xff09;技术的综述文章&#xff0c;详细描述了现有的ST技术及其发展方向。 检测生物分子的新技术一直是生物进步的关键驱动力。在检测生物分子时&#xff0c;研究人员在选择实验方法时一直面临着关键…

CENTOS上的网络安全工具(十四)搬到Docker上(2)?

既然说要搬到Docker上&#xff0c;那么肯定是要把咱日常习惯用的那些东西都往docker上堆一堆看的。我最先考虑的居然是SSH&#xff0c;乃至于到现在我都不知道我为什么第一个想到的是SSH——因为对虚拟机来说&#xff0c;首先考虑的当然是如何远程管理集群中的每个机器&#xf…

iptables用法总结

iptables 是集成在 Linux 内核中的包过滤防火墙系统。使用 iptables 可以添加、删除具体的过滤规则&#xff0c;iptables 默认维护着 4 个表和 5 个链&#xff0c;所有的防火墙策略规则都被分别写入这些表与链中。 1、iptables语法格式 iptables 命令的基本语法格式如下&…

C++ 基础笔记(入门到循环)

目录 1.认识C —— 初窥门径 一、C程序框架&#xff08;8分&#xff09; 二、语言规范&#xff08;16分&#xff09; 三、DEV-C软件&#xff08;下载链接&#xff09; 四、计算机快捷键 五、输入输出的应用 2.变量与赋值 —— 脚踏实地 2.1 变量类型 2.2 变量类型与变…

一文详解名字分类(字符级RNN)

目录 一.前言 二.数据预处理 三.构造神经网络 四.训练 五.评价结果&#xff08;预测&#xff09; 一.前言 我们将构建和训练字符级RNN来对单词进行分类。字符级RNN将单词作为一系列字符读取&#xff0c;在每一步输出预测和“隐藏状态”&#xff0c;将其先前的隐藏 状态输…

02-MySQL数据管理

目录 DDL&#xff08;数据操作语言&#xff09; 添加数据 添加student表数据 修改数据 WHERE条件子句 修改student表数据 删除数据 删除student表数据 总结&#xff1a; DDL&#xff08;数据操作语言&#xff09; 用于操作数据库对象中所包含的数据 关键字&#xff1…

STM32的光敏检测自动智能窗帘控制系统proteus设计

STM32的光敏检测自动智能窗帘控制系统proteus设计 ( proteus仿真程序演示视频&#xff09; 仿真图proteus 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;C0074 主要功能&#xff1a; 结合实际情况&#xff0c;基于STM32单片机设计一…

ATTCK-T1078-001-默认账户

0x01基础信息 具体信息详情ATT&CK编号T1078-001所属战术阶段初始访问操作系统windows 7 旗舰版 SP1创建时间2022年11月10日监测平台火绒安全、火绒剑、sysmon 0x02技术原理 攻击者可能会获取和滥用默认帐户的凭据&#xff0c;以作为获得初始访问、持久性、特权升级或防御…

Python用一行代码,截取图片

前言 本文是该专栏的第3篇,后面会持续分享python的各种黑科技知识,值得关注。 在工作上,有些时候可能需要用到代码来进行自动截图,比如说需要图文识别,进行数据信息抽取的时候,能自动定位截图无疑是很好的办法。 对python而言,截图方法其实有很多,但笔者下面要介绍的…

活动明天见 | DataFunSummit 2022 AI基础软件架构峰会圆桌会

11月16日晚 19&#xff1a;30-21:00&#xff0c;第四范式技术副总裁、OpenMLDB 项目发起人郑曌受邀主持DataFunSummit 2022 AI基础软件架构峰会圆桌会&#xff0c;将与各位资深专家在线上做深度的交流分享&#xff0c;欢迎大家届时收看。 开源机器学习数据库 OpenMLDB **活动时…

全国产三防加固计算机

国产三防加固计算机&#xff0c;本文指的是CPU为国产飞腾D2000处理器、操作系统为国产麒麟V10 SP1系统&#xff0c;整机方案采用全国产化设计。 达梦数据库是由武汉达梦数据库股份有限公司推出的具有完全自主知识产权的高性能数据库管理系统&#xff0c;简称DM。达梦数据库管理…

“辣条一哥”卫龙冲击港股IPO,我又吃出一家上市公司

一、公司简介 卫龙作为国内领先的辣味休闲食品企业&#xff0c;是目前国内辣味食品当之无愧的第一品牌。据2021年零售销售额计&#xff0c;公司在辣味休闲食品企业中排名第一&#xff0c;市场份额达到了6.2%&#xff0c;是一款备受年轻消费者喜爱的休闲食品品牌。天眼查App显示…

vue3之实现响应式数据ref和reactive

用途 ref、reactive都是vue3提供实现响应式数据的方法 ref() 接受一个内部值&#xff0c;返回一个响应式的、可更改的ref对象&#xff0c;此对象只有一个指向其内部的属性.value ref可以说是简化版的reactive&#xff0c;与reactive的区别则是 ref是对某一个数据类型的单独…

测试工程师面试题

很多软件测试工程师在面试的时候都会遇到考官给的各种各样的面试题&#xff0c;这也反应了测试工程师对企业的重要性&#xff0c;面试通常分为以下几个方面&#xff0c;由于篇幅有限&#xff0c;在这里就只给大家分享一些比较常见的问题。 01 自我介绍 这里我不分享如何自我介…

js 网格卡片交换动画

关键技术&#xff1a;animate(keyframes, options) keyframes 关键帧对象数组&#xff0c;或一个关键帧对象&#xff08;其属性为可迭代值的数组&#xff09; 代表动画持续时间的整数&#xff08;以毫秒为单位&#xff09;&#xff0c;或者一个包含一个或多个时间属性 参考传送…

C# 学习之路(类的基本概念)

C# 学习之路&#xff08;类的基本概念&#xff09; 类的概述 类是一种活动的数据结构 程序的数据和功能被组织为逻辑上相关的数据项和函数封装的集合&#xff0c;并称为类 类包含数据成员和函数成员&#xff1a; 数据成员&#xff1a;存储与类或类的实例相关的数据&#xff08…

Linux条件变量

一、条件变量函数 1&#xff0c;条件变量 条件变量&#xff1a;用来描述某种临界资源是否就绪的一种数据化描述。通常要配合mutex一起使用。 2&#xff0c;初始化 pthread_connd_init: 同样有一个静态的和一个动态的。 其中cond是需要初始化的条件变量&#xff0c;attr传…

在线书法培训迎来新风口

随着社会教育水平的不断提高&#xff0c;书法不再是独属于某个年龄层的爱好&#xff0c;开始被越来越多人欣赏和重视。 写一手好字&#xff0c;对每一个人来说都是一个加分“外挂”。在考场上&#xff0c;一手好字无疑可以让阅卷老师在心中自然加分&#xff1b;在职场中&#…

源码深度解析之 Spring IOC

1. 基础知识 1.1 什么是 Spring IOC &#xff1f; IOC 不是一种技术&#xff0c;只是一种思想&#xff0c;一个重要的面向对象编程的法则&#xff0c;它能指导我们如何设计出松耦合、更优良的程序。 传统应用程序都是由我们在类内部主动创建依赖对象&#xff0c;从而导致类与…

Vue--》自定义指令的使用讲解

目录 自定义指令 自定义指令的分类 私有自定义指令&#xff1a; 全局自定义指令&#xff1a; 总结 自定义指令 vue官方提供了v-text、v-for、v-model、v-if等常用的指令&#xff0c;还允许开发者自定义指令。 自定义指令的分类 私有自定义指令&#xff1a; 在每个vue组…