C++面向对象(类和对象)—— 多态篇

微软技术分享 微软全球最有价值专家
全栈领域优质创作者
博客专家认证
2025-06-07 08:02:19

文章目录

七、多态

7.1多态的基本概念

  • 多态是C++面向对象三大特性之一 ,其指同一操作作用于不同对象上,可以产生不同的行为。 多态 主要基于 继承重写 所实现,当父类拥有的 属性方法被多个子类继承后,子类根据自身的情况对继承自父类的方法进行重新,可以表现出不同的行为。

例如:同为人类的理发师和演员,当执行 cut 操作时,理发师的行为是剪发,演员的行为是停止表演,不同的对象,所表现的行为是不一样的

  • 多态分为两类:

  • 静态多态:>函数重载 和 运算符重载属于静态多态,复用函数名

  • 动态多态:派生类和虚函数实现运行时多态

  • 静态多态和动态多态的区别:

  • 静态多态的函数地址早绑定 - 编译阶段确定函数地址>
  • 动态多态的函数地址晚绑定 - 运行阶段确定函数地址>

7.1.1静态多态 - 地址早绑定

#include<iostream>
using namespace std;

class Animal {
public:
    void speak()
    {
        cout << "动物在说话" << endl;
    }
};

class Cat : public Animal {
public:
    void speak()
    {
        cout << "喵喵喵~~" << endl;
    }
}; 

//执行说话的函数
//静态多态 - 地址早绑定,在编译阶段就确定了函数的地址
void doSpeak(Animal& animal){
    animal.speak();
}

void test(){ Cat cat;doSpeak(cat); }
int main(){ test();return 0; }

https://i-blog.csdnimg.cn/direct/b49a8f7ca0dd473caef39094f8e3e394.png

https://i-blog.csdnimg.cn/direct/643f7fe4790b43d5b8ab406d6fa6a323.png

https://i-blog.csdnimg.cn/direct/17b31cf2549d44bf852d8b20c99ac021.png

  • C++中允许基类与派生类(父类和子类)的数据转换, 并且无需强制类型转换,父类的指针(或引用)可直接指向(或接收)子类对象

7.1.2多态多态 - 地址晚绑定 - 虚函数

  • 使函数地址在运行阶段绑定 - 地址晚绑定
  • 使用虚函数作用域基类上
class Animal{
public:
    //虚函数 - 地址晚绑定
    virtual void speak()
    {
        cout << "动物在说话" << endl;
    }
};

https://i-blog.csdnimg.cn/direct/69b51692b8d44a45affa4d90831599a9.png


7.1.3动态多态的满足条件

1.需要存在**继承**关系

2.**子类须<font color="Biue">重写</font>父类的<font color=MediumPurple>虚函数</font>**

+ **<font color="Blue">函数重写</font>**与<font color="Blue">**函数重载**</font>不同,后者是函数的类型相同(返回值同)、函数名相同,但函数的参数列表不同;前者则是函数返回类型、函数名、函数参数列表全都相同。
C++
    class Animal{
    public:
            //虚函数 - 地址晚绑定
        virtual void speak()
        {
            cout << "动物在说话" << endl;
        }
    };


    class Cat : public Animal {
    public:
        //子类重写父类的虚函数
        void speak() --->virtual可写在子类上,也可不写
        {
            cout << "喵喵喵~~" << endl;
        }
    }; 

7.1.4动态多态的调用

  • 父类的指针(或引用),指向子类的对象
C++
    //(Animal)父类的指针(或引用) 指向 子类对象
    Animal& animal = cat;
    void doSpeak(Animal& animal)
        {
            animal.speak();
        }

        doSpeak(cat);

7.1.5多态技术对虚函数的调用

多态调用核心:父类的指针(或引用)指向子类实例化出的对象

#include<iostream>
using namespace std;
class Base {
public:

    //纯虚函数 - 只要类中有一个纯虚函数,那么这个类就被称为抽象类
    virtual void func() = 0;

};

class Son : public Base {
public:
    virtual void func() 
    {
        cout << "纯虚函数 func() 的调用!" << endl;
    }
};

void test(){
    //利用多态的技术调用:父类的指针(或引用)指向子类对象
    Base* base = new Son;
    base->func();
}
int main(){test();return 0;}

https://i-blog.csdnimg.cn/direct/694c310730a749428dc85e0763bedbdc.png


7.2多态的深度解析

7.2.1虚函数指针

  • 未加入 virtual修饰的 Animal 类的大小
  • 此时 Animal 类中只存在一个非静态的成员函数(分开存储,不属于类的dui’x),类似于空类
#include<iostream>
using namespace std;

class Animal {
public:
    void speak()
    {
        cout << "动物在说话" << endl;
    }
};

class Cat : public Animal {
public:
    void speak()
    {
        cout << "喵喵喵~~" << endl;
    }
};

class Dog : public Animal {
public:
    void speak()
    {
        cout << "汪汪汪~~" << endl;
    }
};
void doSpeak(Animal& animal) {
    animal.speak();
}

void test() {
    Cat cat;
    doSpeak(cat);

    Dog dog;
    doSpeak(dog);
}

void test01() {
    cout << "sizeof(Animal) == " << sizeof(Animal) << endl;
}
int main() { test(); test01();  return 0; }

https://i-blog.csdnimg.cn/direct/d38e03c132534ade8f26de4d3bb895d4.png


  • 加入关键字 virtual ,类内部的结构发生了改变
C++
        class Animal {
        public:
        virtual void speak()
        {
            cout << "动物在说话" << endl;
        }
    };

https://i-blog.csdnimg.cn/direct/368c784538fb4daf98dc3757bb3e650d.png

  • x32位 — 4
  • x64位 — 8

7.2.2类内部结构深度剖析

  • 对虚函数的深度剖析
c++
    class Animal {
    public:
        virtual void speak()
        {
            cout << "动物在说话" << endl;
        }
    };

https://i-blog.csdnimg.cn/direct/cdef5126683841aebe880ff6a17fbf77.png

https://i-blog.csdnimg.cn/direct/5320e0160a174364a6d6b9717f3be41e.png


  • 继续对继承虚函数的子类,进行分析: 不存在重写时,请观察虚函数列表中的数据
C++
    class Cat : public Animal {
    public:
        
        //不存在重写时,请观察虚函数列表中的数据
        
    };

https://i-blog.csdnimg.cn/direct/ceaacc887fd54d2dbd389163b5055299.png

https://i-blog.csdnimg.cn/direct/51426b5fc1cd46e39976f1ec901e96f2.png

  • 当子类重写了父类的虚函数,子类的虚函数表内部,会替换为子类的虚函数地址
C++
    class Cat : public Animal {
    public:
    
    //子类对父类的虚函数进行重写
        void speak()
        {
            cout << "喵喵喵~~" << endl;
        }

    };

https://i-blog.csdnimg.cn/direct/231a14d714554c03a61eaea478a983e5.png

https://i-blog.csdnimg.cn/direct/bfc1f62cda1245078f47abdfc422fb0c.png


7.3多态的案例1 — 计算器类

  • 案例描述: ​ 分别利用普通写法和多态技术、设计实现两个操作数进行运算的计算器类
  • 多态的优点:
  • 代码组织结构清晰
  • 可读性强
  • 利于前期、后期的扩展和维护性高

7.3.1普通写法

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

//普通写法:
class Calculator {
public:

    int getResult(string oper){
        if (oper == "+") return this->Num1 + this->Num2;

        else if (oper == "-") return this->Num1 - this->Num2;

        else if (oper == "*") return this->Num1 * this->Num2;

        else if (oper == "/") return this->Num1 / this->Num2;

        else if (oper == "%") return this->Num1 % this->Num2;
    }

    int Num1;//操作数1
    int Num2;//操作数2
};

void test(){
    Calculator c;

    c.Num1 = 10;
    c.Num2 = 20;

    cout << c.Num1 << " + " << c.Num2 << " == " << c.getResult("+") << endl;

    cout << c.Num1 << " - " << c.Num2 << " == " << c.getResult("-") << endl;

    cout << c.Num1 << " * " << c.Num2 << " == " << c.getResult("*") << endl;

    cout << c.Num1 << " * " << c.Num2 << " == " << c.getResult("/") << endl;

    cout << c.Num1 << " * " << c.Num2 << " == " << c.getResult("%") << endl;
}
int main(){test();return 0;}

https://i-blog.csdnimg.cn/direct/9f5a7f5c391347b5beb60410e5cd3a3d.png


7.3.2多态、抽象类

  • 在真实的开发中,提倡一种原则:开闭原则
  • 对扩展进行开发、对修改进行关闭
#include<iostream>
using namespace std;
#include<string>

//开创一个抽象类
class AbstractCalculator {
public:

    //纯虚函数
    virtual int getResult() = 0;

    int Num1;
    int Num2;
};

//加法计算器类
class AddCalculator : public AbstractCalculator {
public:

    virtual int getResult()
    {
        return Num1 + Num2;
    }
};

//减法计算器类
class SubCalculator : public AbstractCalculator {
public:

    virtual int getResult()
    {
        return Num1 - Num2;
    }
};

//乘法计算器类
class MulCalculator : public AbstractCalculator {
public:
    virtual int getResult()
    {
        return Num1 * Num2;
    }
};

void test01() {
    //多态的使用条件 - 父类的指针或引用指向子类对象

    //加法运算器
    AbstractCalculator* abc = new AddCalculator;//在堆区创建一个AddCalculator类型的加法对象,并使用父类指针去指向这块区域
    abc->Num1 = 10;
    abc->Num2 = 20;
    cout << abc->Num1 << " + " << abc->Num2 << " == " << abc->getResult() << endl;

    //堆区数据手动开辟,手动释放
    delete abc;

    //减法运算器
    abc = new SubCalculator;
    abc->Num1 = 200;
    abc->Num2 = 30;
    cout << abc->Num1 << " - " << abc->Num2 << " == " << abc->getResult() << endl;
    delete abc;

    //乘法运算器
    abc = new MulCalculator;
    abc->Num1 = 40;
    abc->Num2 = 79;
    cout << abc->Num1 << " * " << abc->Num2 << " == " << abc->getResult() << endl;
    delete abc;
}
int main(){test01();return 0;}

https://i-blog.csdnimg.cn/direct/e28d34ccc47442f7885f12596cce941f.png

  • 总结:在C++开发中,提倡利用多态设计程序架构。

7.4纯虚函数和抽象类

  • 多态中,通常父类中虚函数>的实现是毫无意义的,主要是为了调用子类重写的内容,因此可以将虚函数改为纯虚函数>
  • 纯虚函数>的语法:virtual 返回值类型 函数名 (参数列表) = 0;
  • 当类中有了**纯虚函数>**,这个类也被成为抽象类

抽象类的特点:

1.无法实例化对象

2.子类必须重写抽象类中的纯虚函数,否则也属于抽象类,且无法实例化对象


7.4.1抽象类特点:无法实例化对象

  • 特性一:无论在栈区,又或是堆区,都无法实例化出对象
#include<iostream>
using namespace std;
class Base {
public:

    //纯虚函数 - 只要类中有一个纯虚函数,那么这个类就被称为抽象类
    
    virtual void func() = 0;

};
void test01()
{
    //抽象类特点:1.无法实例化对象
    Base b;//a.栈区上-->false
    new Base;//b.堆区上-->false
}

https://i-blog.csdnimg.cn/direct/e622d2ce272a4dfc88ebe440c4830fe1.png


7.4.2重写父类的纯虚函数

  • **特性二:抽象类的子类,必须要重写父类中的纯虚函数,否则也属于抽象类,即 “子类也无法实例化出对象” **
C++
    class Son : public Base {
    public:
    
    };

    void test(){
        Son s;
        new Son;
    }

https://i-blog.csdnimg.cn/direct/dffcae42deeb4de4b92bdae745509a01.png


  • 子类重写父类中的纯虚函数

https://i-blog.csdnimg.cn/direct/408bbeab27c64fb49917dd61be09be12.png


https://i-blog.csdnimg.cn/direct/672bce864ea84d4e9b8f8c39d0830233.png


7.5多态案例2

  • 案例描述: ​ 制作饮品的常规流程:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品的基类,提供子类制作咖啡和茶叶

https://i-blog.csdnimg.cn/direct/0a682d013d8a482e93a4a8e853ddea9e.png

#include<iostream>
using namespace std;

class AbstractDrinking {
public:

    //煮水
    virtual void Boil() = 0;

    //冲泡
    virtual void Brew() = 0;

    //倒入杯中
    virtual void PourInCup() = 0;

    //加入辅料
    virtual void PutSomething() = 0;

    //提供制作饮品功能的对外接口
    void MakeDrink()
    {
        Boil();
        Brew();
        PourInCup();
        PutSomething();
    }
};

//制作咖啡
class Coffe : public AbstractDrinking {
public:
    //在子类中,重写父类的纯虚函数

    virtual void Boil() {
        cout << "煮水模式已经开启!" << endl;
    }

    virtual void Brew() {
        cout << "加热完毕,准备冲泡咖啡!" << endl;
    }

    virtual void PourInCup() {
        cout << "正在倒入杯中!" << endl;
    }

    virtual void PutSomething() {
        cout << "加入糖和牛奶!" << endl;
    }
};

//制作茶叶
class Tea : public AbstractDrinking {
public:

    virtual void Boil() {
        cout << "煮水模式已经开启!" << endl;
    }
    virtual void Brew() {
        cout << "加热完毕,准备冲泡茶叶!" << endl;
    }
    virtual void PourInCup() {
        cout << "正在倒入杯中!" << endl;
    }
    virtual void PutSomething() {
        cout << "加入枸杞!" << endl;
    }
};

//运作功能
void doWork(AbstractDrinking* abc){
    abc->MakeDrink();
    delete abs;//释放堆区数据
}

void test() {
    //调用制作功能
    doWork(new Coffe);//使父类指针去指向子类对象

    //doWork(new Tea);
}
int main(){test();return 0;}

https://i-blog.csdnimg.cn/direct/763025c91d9f43d79ba052c3cc25ce55.png

https://i-blog.csdnimg.cn/direct/383cff6b5c534a1f808db723c76e2fc2.png


7.5虚析构与纯虚析构

  • 多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码 - 造成堆区数据的泄露
    注意:虚析构与纯虚析构之间无法共存
  • 解决方法: ​ 将父类中的析构函数改为虚析构函数纯虚析构函数
  • 虚析构纯虚析构的共性:
  • 可以解决父类指针无法释放子类对象的问题
  • 都需要具体的函数实现
  • 虚析构纯虚析构的差异:
  • 纯虚析构属于抽象类,无法实例化对象
  • 虚析构语法:virtual ~类名(){}
  • 纯虚析构的语法:virtual ~类名() = 0;
  • 纯虚析构纯虚函数的差异:
  • 前者需要声明,也实现
  • 后置只需声明即可

#include<iostream>
using namespace std;

class Animal {
public:

    virtual void speak()
    {
        cout << "动物在说话!" << endl;
    }
};

class Cat : public Animal {
public:

    //在子类中重写父类虚函数
    virtual void speak()
    {
        cout << "喵喵喵~~" << endl;
    }
};

void test()
{
    发生多态 - 地址晚绑定
    Animal* animal = new Cat;
    animal->speak();
    delete animal;
}
int main(){test();return 0;}

https://i-blog.csdnimg.cn/direct/d9396f7fcd184c908577423406f7c83f.png


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

class Animal {
public:

    Animal()
    {
        cout << "Animal 的构造函数调用!" << endl;
    }

    ~Animal()
    {
        cout << "Animal 的析构函数调用!" << endl;
    }

    virtual void speak()
    {
        cout << "动物在说话!" << endl;
    }

    
};

class Cat : public Animal {
public:

    //Cat构造函数
    Cat(string name)//在创建子类构造/析构函数之前,要先有父类的构造/析构,先走爹再走儿子
    {
        cout << "Cat 的构造函数调用!" << endl;

        //将接收的name创建到堆区,并使用成员对象对其进行维护
        m_Name = new string(name);
    }


    //在子类中重写父类虚函数
    virtual void speak()
    {
        cout << *m_Name << "小猫在:喵喵喵~~" << endl;
    }

    //释放堆区数据
    ~Cat() 
    {
        if (m_Name != NULL) {
            cout << "Cat 析构函数调用!" << endl;
            delete m_Name;
            m_Name = NULL;
        }
    }

    string* m_Name;//使成员对象,被创建在堆区
};

void test(){
    Animal* animal = new Cat("啦啦啦");
    animal->speak();
    delete animal;
}
int main(){test();return 0;}

https://i-blog.csdnimg.cn/direct/a10f4eebe9b14219813d0529f8ac4321.png

https://i-blog.csdnimg.cn/direct/5c07062157584161a014c2ce46bc5a5f.png

  • 由代码的输出结果,可知Cat的析构函数被缺失掉了

产生原因:

C++
    void test(){
        Animal* animal = new Cat("啦啦啦");
        animal->speak();
//父类指针在进行析构的时候,不会调用子类中的析构函数,这导致子类如果存在堆区的属性(或数据),就会出现内存泄露的情况
        delete animal;
    }
  • 解决方法:将父类中的析构函数,改为虚析构
C++
    virtual ~Animal()
    {
        cout << "Animal 的析构函数调用!" << endl;
    }

https://i-blog.csdnimg.cn/direct/effb457b02b141caa49050879ecc04ca.png


  • 同理也可以使用纯虚析构解决**父类指针无法释放子类对象的问题,但要注意虚析构纯虚析构**之间无法共存。
C++
    virtual ~Animal() = 0;
  • 此时会出现一个问题

https://i-blog.csdnimg.cn/direct/0b5689740a284a5aa5766ad490dd5a34.png

无法解析的外部命令,一般是在链接阶段所出现的错误,因为当我们只写virtual ~Animal() = 0;,这其实只是一个声明,而并没有任何代码的实现

C++
    class Animal {
    public:

        Animal()
        {
            cout << "Animal 的构造函数调用!" << endl;
        }
        //类内声明纯虚析构
        virtual ~Animal() = 0;//纯虚析构

        virtual void speak()
        {
            cout << "动物在说话!" << endl;
        }        
    
    };
//类外实现纯虚析构
Animal::~Animal()
{
    cout << "Animal 的纯虚析构函数调用!" << endl;
}
  • 因此纯虚析构纯虚函数不同,前者需声明 + 实现,后者只须声明

  • 此外,有了纯虚析构后,这个类也属于抽象类,无法实例化对象
  • 既然我们学了虚析构纯虚析构,难道以后写代码都要去写它们吗?显然不是的,我们的这个案例比较特殊。
  • 在我们的子类中有些数据,被我们开辟到堆区 ( string* m_Name ) ,所以我们必须执行我们子类当中的析构代码,但使用多态,我们是无法执行子类的析构函数的 —— 父类指针无法释放子类对象
  • 因此我们才在父类中加入虚/纯虚析构来解决这一问题

总结:

​ 1.虚/纯虚析构,是用来解决父类指针无法释放子类对象的问题

​ 2.如果子类中没有堆区数据,可以不写虚析构/纯虚析构函数>

​ 3.拥有纯虚析构>的类也属于抽象类


7.6多态案例三 — 电脑组装

  • 案例描述: ​ 电脑主要组成部件为CPU ( 用于计算 ),显卡 ( 用于显示 ),内存条 ( 用于存储 ) 。将每个零件封装出==抽象基类==,并且提供不同的厂商生产不同的零件 ( 例如,Inter厂商、Lenovo厂商 ) ,创建电脑类并提供让电脑运作的函数,并且调用使每个零件工作的接口,测试时组装三台不同的电脑进行工作

https://i-blog.csdnimg.cn/direct/ecd2fdeff48e4ba48aa8cfc9d313341d.png

https://i-blog.csdnimg.cn/direct/40aa0e02ea5242bfb9597833579c3828.png


https://i-blog.csdnimg.cn/direct/0e399de82c544c1c8d27c4249008f426.png


7.6.1设计思路

  • 抽象出每个零件的类
  • 创建电脑类 ( 相当于框架 ) ,在电脑类中使用构造函数初始化三个零件的指针
  • 在电脑类中提供一个工作的函数,在其中提供每个工作零件的接口
  • 具体零件的厂商
  • 测试阶段,开始组装三台不同的电脑

7.6.2项目实现

#include<iostream>
using namespace std;

//1.抽象不同的零件类
//抽象CPU类
class Cpu {
public:

    //抽象的计算函数
    virtual void calculate() = 0;
};

//抽象显卡类
class VideoCard {
public:

    //抽象的显示函数
    virtual void display() = 0;
};

抽象内存条类
class Memory {
public:

    //抽象的存储函数
    virtual void storage() = 0;
};

class Computer {
public:

    //为三个指针提供接收
    Computer(Cpu* cpu, VideoCard* vdcd, Memory* memroycard)
    {
        this->cpu = cpu;
        this->vdcd = vdcd;
        this->memroycard = memroycard;
    }

    //提供运作的函数
    void doWork()
    {
        //使零件工作起来,调用接口
        this->cpu->calculate();
        this->vdcd->display();
        this->memroycard->storage();
    }

    //提供析构函数,将三个电脑零件(堆区中的数据)释放掉
    ~Computer() 
    {
        if (this->cpu != NULL)
        {
            delete this->cpu;
            this->cpu = NULL;
        }

        if (this->vdcd != NULL)
        {
            delete this->vdcd;
            this->vdcd = NULL;
        }

        if (this->memroycard != NULL)
        {
            delete this->memroycard;
            this->memroycard = NULL;
        }
    }

private:
    Cpu* cpu;//CPU零件指针
    VideoCard* vdcd;//显卡零件指针
    Memory* memroycard;//内存条零件指针
};


//实现具体的厂商 - Inter
class InterCpu : public Cpu {
public:
    //子类重写父类中的纯虚函数
    virtual void calculate() 
    {
        cout << "Inter 的CPU 开始计算了!" << endl;
    }
};

class InterVideoCard : public VideoCard {
public:
    //子类重写父类中的纯虚函数
    virtual void display()
    {
        cout << "Inter 的显卡 开始显示了!" << endl;
    }
};

class InterMemory : public Memory {
public:
    //子类重写父类中的纯虚函数
    virtual void storage()
    {
        cout << "Inter 的内存条 开始存储了!" << endl;
    }
};

//Lenovo厂商
class LenovoCpu : public Cpu {
public:
    //子类重写父类中的纯虚函数
    virtual void calculate()
    {
        cout << "Lenovo 的CPU 开始计算了!" << endl;
    }
};

class LenovoVideoCard : public VideoCard {
public:
    //子类重写父类中的纯虚函数
    virtual void display()
    {
        cout << "Lenovo 的显卡 开始显示了!" << endl;
    }
};

class LenovoMemory : public Memory {
public:
    //子类重写父类中的纯虚函数
    virtual void storage()
    {
        cout << "Lenovo 的内存条 开始存储了!" << endl;
    }
};

void test01() 
{
    //组装第一台电脑的零件
    //多态 - 父类指针指向子类对象
    Cpu* INcpu = new InterCpu;
    VideoCard* INvdcd = new InterVideoCard;
    Memory* INmemory = new InterMemory;

    //创建第一台电脑
    Computer* computer1 = new Computer(INcpu, INvdcd, INmemory);
    computer1->doWork();
    delete computer1;

    /*           -----> 可以提供析构函数,将三个在堆区开辟的数据释放
    delete INcpu;
    delete INvdcd;
    delete INmemory;
    */
    cout << "--------------------------" << endl;
}

void test02()
{
    Cpu* Levcpu = new LenovoCpu;
    VideoCard* Levvc = new LenovoVideoCard;
    Memory* Levmemory = new LenovoMemory;

    //创建第二台电脑
    Computer* computer2 = new Computer(Levcpu, Levvc, Levmemory);
    computer2->doWork();
    delete computer2;
}
int main(){test01();test02();return 0;}

https://i-blog.csdnimg.cn/direct/69391d95b06d44149fcafd5420d6e4aa.png


文章来源: https://blog.csdn.net/2401_87692970/article/details/146429243
版权声明: 本文为博主原创文章,遵循CC 4.0 BY-SA 知识共享协议,转载请附上原文出处链接和本声明。


...全文
32 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

5,411

社区成员

发帖
与我相关
我的任务
社区描述
微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。
windowsmicrosoft 企业社区
社区管理员
  • 山月照空舟
  • 郑子铭
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。

予力众生,成就不凡!微软致力于用技术改变世界,助力企业实现数字化转型。

试试用AI创作助手写篇文章吧