前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >从父类到子类:C++ 继承的奇妙旅程(2)

从父类到子类:C++ 继承的奇妙旅程(2)

作者头像
用户11295429
发布于 2025-05-11 12:43:13
发布于 2025-05-11 12:43:13
7600
代码可运行
举报
文章被收录于专栏:王的博客专栏王的博客专栏
运行总次数:0
代码可运行

前言:

        各位代码航海家,欢迎回到C++继承宇宙!上回我们解锁了继承的「基础装备包」,成功驯服了publicprotected和花式成员隐藏术。但——

        ⚠️前方高能预警: 继承世界的暗流涌动远不止于此!今天我们将勇闯三大神秘海域:

  1. 多继承の百慕大三角 👻——当你的类同时认了两个"爹"
  2. 虚继承の量子纠缠 ⚛️——专治"菱形继承"引发的时空悖论
  3. 继承构造/析构の连锁反应 💥——比《信条》更烧脑的逆向工程

        准备好你的IDE光剑和调试护盾,我们即将潜入继承深渊!

🎮 本关Boss预告

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 爷爷 {};  
class 爸爸1 : virtual public 爷爷 {}; // 虚继承!  
class 爸爸2 : virtual public 爷爷 {};  
class  : public 爸爸1, public 爸爸2 {}; // 多继承の最终形态!  

灵魂拷问

  • 爷爷的遗产被爸爸1爸爸2重复继承时,会继承几份祖传代码?
  • 为什么祖师爷要发明"虚继承"这种黑科技?
  • 构造函数们究竟在继承链上玩什么接力赛?

(摸鱼提示:文末附赠「菱形继承生存指南」,保你跳出编译错误的黑洞!)

☕ 建议装备

  • 咖啡因补给包 ×1
  • 防止指针错乱的思维导图 ×1
  • 暂时忘记Java/Python的勇气 ×1

⚡ 3秒后进入继承下篇—— 程序员,你是否选择「接受挑战」?

(按下F5继续执行代码...🚀)

1.派生类的默认成员函数

1.1.四个常见的默认成员函数

        通过之前的学习,我们知晓,C++有六种默认构造函数,忘记的或者是不知晓的读者可以看我之前写过的初始C嘎嘎的文章,那里详细记载了,当然,主要的默认成员函数其实有四种:构造函数、拷贝构造函数、赋值运算符重载,析构函数默认的意思指的是我们不写,编译器会帮我们自动生成一个,那么在派生类中,这四种函数又是如何生成的呢?

        1.派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。其实我们可以把基类当做是一个自定义类型的成员变量,众所周知,自定义类型的成员变量会调用自己的默认构造函数,如果没有默认构造函数的时候,编译器就会报错,必须显示的去调用构造函数。而基类的默认构造也和这个类似,大多数情况我们都是不需要自己调用构造函数的,当然,不排除我们没写默认构造函数,那么它的用法如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person
{
public:
    Person(const string& name) :t_name(name)   //这里就用一个正常的构造函数,但不是默认构造函数
    {}
protected:
    string t_name;
};class Student :public Person
{
public:
    Student(const string& _t_name,const string& name) : Person(_t_name),_name(name)  //直接调用其父类的构造函数即可,当做整体进行构造
    {}
protected:
    string _name;
};

        2.派生类对象初始化先调用基类构造再调派生类构造。这个很好去理解,因为基类是比派生类的成员变量出现的早的,所以出现最早的优先调用构造函数,所以先调用基类的构造在调用子类的构造。

        3.派生类的拷贝构造函数必须调用基类的拷贝构造来完成基类的拷贝初始化。这个也是比较好理解的,因为拷贝构造需要我们传入对应的对象,不像默认构造函数那样有缺省值直接调用缺省值就好,所以它要求我们去显示的调用拷贝构造,这里的知识和我们第一篇继承的知识联系在了一起,不知道读者是否还记得“切片”,也就是public继承的派生类对象可以赋值给基类的指针 / 基类的引用。也就是如下图所示:

        此时我们仅需在派生类的拷贝构造函数中传入派生类对象的引用,并且基类的拷贝构造函数的参数必须是基类的引用,此时我们就可以通过切片把派生类对象中基类的一部分切给要进行拷贝构造的派生类的基类部分了,可谓是非常的优美。下面我将通过一个例子让各位了解用法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person
{
public:
    Person(Person& s1):t_name(s1.t_name)
    {}
protected:
    string t_name;
};class Student :public Person
{
public:
    Student(Student& s1): Person(s1),_name(s1._name)  //直接把对象传到基类即可
    {}
protected:
    string _name;
};

        4.派生类的operator=必须要调用基类的operator=完成基类的复制。需要注意的是派生类的operator=隐藏了基类的operator=,所以显示调用基类的operator=,需要指定基类作用域。这个为什么显示调用和拷贝构造是一样的,这里我就不详说了,不过这里也是牵扯到了上篇博客的一个小知识点:隐藏的知识,当函数名相同的时候,并且函数分别属于基类的作用域和派生类的作用域时,那么此时就是构成了隐藏关系。而基类和子类的赋值运算符重载名字是一模一样的,所以构成了隐藏关系,此时我们需要指定类域才可以调用基类的赋值运算符重载,它的用法如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person
{
public:
    Person& operator=(const Person& s1)
    {
        t_name = s1.t_name;
        return *this;
    }
protected:
    string t_name;
};class Student :public Person
{
public:
    Student& operator=(const Student& s1)
    {
        Person::operator=(s1); //一定要指明基类的作用域
        _name = s1._name;
        return *this;
    }
protected:
    string _name;
};

        5.派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。这个也是牵扯到了我们第一次初学C++类和对象的时候学到的知识:后定义的先析构,因为派生类的成员是后来定义的,所以它是最开始析构的,所以我们先清理派生类的成员函数,在进行基类成员的清理。当然,析构函数我们最好还是不要显示的调用,至于为何,请看第七点。

        6.派生类对象析构清理先调用派生类析构再调基类的析构。这个上面解释了,我就不细说了。

        7.因为多态中一些场景析构函数需要构成重写,重写的条件之一是函数名相同(这个我们多态章节会讲解)。那么编译器会对析构函数名进行特殊处理,处理成destructor(),所以基类析构函数不加virtual的情况下,派生类析构函数和基类析构函数构成隐藏关系。所以我的建议就是析构函数我们还是老老实实的让派生类自己去调用基类的析构函数吧,这样比较方便。

        各位读者,看到这里是不是手痒想当"代码界的灭霸"了?别急着敲继承的响指!今天咱们要聊的C++贵族礼仪——如何让类在族谱上写下"此脉单传,永不加粗"!

        想打造这种孤高の王族血统?可不是给构造函数上锁那么简单(那招就像在城堡门口挂"内有恶犬",防得住新手防不住杠精)。C++11早给我们准备了基因改造药剂——final关键字!这玩意儿比皇后的毒苹果还好使:

1.2.实现一个不能被继承的类
方法一

        不知道各位读者是否还记得我上篇文章所讲述的继承方式,基类使用private成员限定符限定的成员是不可以被派生类使用的,那么这就相当于不可以被派生类继承(当然,还是继承下来的,只不过不允许使用)了。所以当我们让基类的构造函数被private限定以后,那么此时派生类就无法调用基类的默认构造函数,从而导致派生类无法实例化出对象,这就意味这个类是无法被继承的。如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person
{
private:
    Person() {}
};class Studnet : public Person
{
public:
    Studnet() {}
public:
};

        不过这个做法是有点不优美的,因为它有个致命的缺陷:“家贼难防”,如果给派生类悄悄的开一个后门:friend通行证(友元),那么此时派生类依然可以调用基类的拷贝构造函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 薛定谔的保险箱 {
private:
    薛定谔的保险箱() {}
    friend class 量子穿墙术; // 偷偷塞钥匙
};class 量子穿墙术 : public 薛定谔的保险箱 { 
    // 竟然成功继承!科学伦理委员会震怒
};

        这个方法的局限性很大,所以准确来说:通过私有化构造函数可以制造伪·不可继承类,但需要配合杜绝friend后门,而C++11的final关键字才是正宗的绝育手术刀~(≧∇≦)/~(这就是方法二)。

方法二

        C++11新增加了一个关键字:final关键字,final修改基类,那么派生类就无法继承了,它的用法如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person final
{
public:
    Person() {}
};class Studnet : public Person
{
public:
    Studnet() {}
public:
};

2.继承和友元

        友元关系不能继承,也就是说基类友元不能访问派生类私有和保护成员。这个很好理解,下面我就一个有趣的例子来给各位说明一下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 祖传咸鱼配方 { // 传男不传女的独门秘方
private:
    int 祖传盐量 = 999; // 传家宝级别的盐值
    friend class 大厨; // 授予传功长老权限
};class 改良版咸鱼配方 : public 祖传咸鱼配方 {
private: 
    int 科技盐量 = 666; // 偷偷加了海克斯科技
};class 大厨 {
public:
    void 烹饪秘术(祖传咸鱼配方& 老坛) {
        老坛.祖传盐量 = 9527; // 畅通无阻(毕竟有friend通行证)
    }void 黑暗料理(改良版咸鱼配方& 新品) {
        // 新品.科技盐量 = 1314; // 报错!编译器怒斥:你只是他爹的基友!
    }
};// 剧情彩蛋:就算逆天改命也不行!
class 逆子配方 : public 祖传咸鱼配方 {
    friend class 大厨; // 试图继承爹的社交圈
private:
    int 叛逆盐量 = 233;
};// 大厨试图搞事情:
void 偷天换日() {
    逆子配方 黑化版;
    黑化版.叛逆盐量 = 666; // 依然报错!编译器冷笑:父辈的friend不是你的ATM机!
}

这波操作生动诠释了:

  1. 友元关系比钢铁直男还直——绝不拐弯继承(派生类不会自动获得基类友元)
  2. 友元权限比小区门禁还严——只认身份证原件(即便派生类主动示好,基类友元也摸不到派生类的私有成员)
  3. 想开后门?除非上演《无间道》——在派生类里重新声明friend(但这样可就背叛革命了)

3.继承和静态成员

        基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个派生类,都只有一个static成员实例。通过一个简单的例子就可以知晓这个定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 魔法始祖 {
public:
    static int 魔力源泉; // 全魔法界共享的充电宝
};
​
int 魔法始祖::魔力源泉 = 100; // 在霍格沃茨地窖初始化class 火系法师 : public 魔法始祖 {};
class 水系法师 : public 魔法始祖 {};
class 风系法师 : public 魔法始祖 {};
​
int main() {
    火系法师 甘道夫;
    水系法师 梅林;
    风系法师 萨尔;// 所有法师共享同一个魔法池
    甘道夫.魔力源泉 += 50;  // 火法师给充电宝续费
    cout << 梅林.魔力源泉 << endl;   // 输出150(水系躺着蹭网)
    
    萨尔.魔力源泉 -= 70;     // 风系法师偷偷下载小电影
    cout << 魔法始祖::魔力源泉 << endl; // 输出80(祖宗家底被败光)
    
    // 见证奇迹的时刻!
    cout << &甘道夫.魔力源泉 << " ←火法地址\n"
         << &梅林.魔力源泉   << " ←水法地址\n"
         << &萨尔.魔力源泉   << " ←风法地址" << endl;
    // 三个地址完全相同,实锤共享内存
}

 这段代码生动诠释了:

  1. 静态成员就像家族银行账户——所有子孙刷的都是同一张卡
  2. 无论通过基类还是派生类访问,操作的都是同一个内存地址
  3. 任一派生类搞事情,全家族成员都要背锅(值同步变化)

4.多继承以及其菱形继承问题

4.1.继承模型

        单继承:一个派生类只有一个直接基类时称这个继承关系为单继承。这个是比较好理解的,因为它的定义就和它的名字一样,下面我给出示例图:

        单继承算是一个比较正常的继承了,但是如果单继承变为了多继承,那么会很逆天!

        (敲黑板)各位程序员请注意,咱们今天要聊的是C++里的"多重身份危机"——多继承和它的狗血连续剧"菱形继承"!


第一幕:多继承の修罗场

想象一下,你是个时间管理大师:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 社畜 : public 打工人, public 乙方舔狗, public 深夜码农 {};

这就是多继承——一个类同时认多个爹。内存布局就像叠罗汉,谁先继承谁在下面:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[打工人][乙方舔狗][深夜码农][社畜的私人数据]

        但问题来了——如果多个爹有同名成员,编译器直接懵逼:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
社畜 张三;
张三._存款 = -10086; // 编译器怒吼:你三个爹都有存款,我该改哪个?!

第二幕:菱形继承の家族伦理剧

        来看这张祖传关系图:

        结果Assistant继承时,老祖宗的基因复制了两份!这就是菱形继承的血泪史:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Assistant 小王;
小王.Student::_name = "学渣"; 
小王.Teacher::_name = "教授"; 
// 实际小王体内住着两个老祖宗,精分现场!

        内存布局宛如祖传玉佩摔成两半:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Student版Person][Teacher版Person][Assistant数据]

        此时访问_name就像问妈妈和老婆掉水里救谁——必须指定爹名:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cout << 小王.Student::_name; // "学渣"
cout << 小王.Teacher::_name; // "教授"

第三幕:虚继承の公证处协议

        C++祭出大招:虚继承!相当于给老祖宗做公证:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Student : virtual public Person {}; // 公证声明
class Teacher : virtual public Person {}; // 同上

        此时孙辈的内存布局变成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[虚表指针][Student数据][虚表指针][Teacher数据][老祖宗Person][Assistant数据]

        虽然解决了数据冗余,但代价是:

  1. 构造顺序堪比宫廷剧——孙辈得直接给老祖宗上供:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Assistant::Assistant() 
    : Person("工具人"), Student(), Teacher() {} // 必须亲自初始化老祖宗
  1. 访问速度像去公证处盖章——多绕一层指针

终幕:多继承の终极考题

来看这道送命题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Basel b1; Base2 b2;
class 缝合怪 : public Basel, public Base2 {};
缝合怪 obj;
Basel* p1 = &obj;
Base2* p2 = &obj;
void* p3 = &obj;

指针地址关系是?

  • A: p1 == p2 == p3 ❌(想得美)
  • B: p1 < p2 < p3 ❌(内存不是等差数列)
  • C: p1 == p3 != p2 ✅(Basel先继承,地址最低)
  • D: p1 != p2 != p3 ❌(p3和p1指向同一起点)

        总结陈词: 多继承就像同时认多个干爹——给钱时很爽,争家产时头大。而菱形继承则是家族内斗的终极形态,虚继承虽然能维稳,但操作难度堪比处理婆媳关系。珍爱生命,远离菱形!(Java笑而不语)

4.2.彩蛋:IO库中的菱形虚拟继承

        其实我们日常使用iostream库就是一个菱形虚拟继承,其结构图如下所示:

5.继承和组合

        各位读者请注意,最后咱们要聊的是面向对象界的"婆媳关系"——继承和组合!这可是代码界的"到底该听妈的还是听媳妇的"终极难题!


第一回合:继承——代码界的家族企业

继承就像你爹开公司,你直接当太子爷继承皇位:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 富二代 : public 土豪爹 {
    // 自动获得爹的别墅、跑车、黑卡
};

优点

  • 是亲生的(is-a关系),直接拿爹的全部家当(包括私房钱)
  • 白嫖式开发(白箱复用),连爹的日记本都能翻

缺点

  • 爹改遗嘱(修改基类),儿子当场破产(代码爆炸)
  • 耦合度堪比连体婴,爹感冒儿子必发烧

经典翻车现场

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class{
public:
    void 传家宝() { cout << "洛阳铲"; }
};class 儿子 : public{};// 某天爹考古入魔:
class{
public:
    void 传家宝() { cout << "盗墓笔记"; } // 从工具升级成知识
};// 儿子:???我铲子呢???

第二回合:组合——代码界的乐高大师

组合就像自己开公司,雇个专业经理人:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 打工人 {
    class 肝帝程序员 员工; // 组合一个996战士
    class AWS云服务器 设备; // 再组个烧钱神器
};

优点

  • 是老板(has-a关系),只关心KPI(接口),不管员工私生活(黑箱复用)
  • 耦合度堪比塑料友情,随时换掉摸鱼员工(维护性好)

经典操作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 特斯拉 {
    Battery 电池;   // 想换宁德时代?换!
    Motor 电机;     // 想用国产?换!
    Autopilot 智驾; // 想用华为?换!(马斯克震怒)
};
// 组合就是:没有什么是换零件解决不了的

第三回合:继承 vs 组合の世纪对决

对比项

继承

组合

关系

你是我儿子(is-a)

你是我工具人(has-a)

耦合度

脐带级绑定

点赞之交

封装性

爹的内裤都被看光

打码级保护

改需求伤害

家族式团灭

换个零件就能活

适用场景

"狗是动物"这种铁律

"车有轮胎"这种可拆卸关系


终极大招:面向对象の生存法则
  1. 能组合就别继承——少认爹少背锅,多个爹多个坟头
  2. 非要继承时
    • 确认关系铁如"企鹅是鸟"(虽然它不会飞)
    • 准备迎接"爹动一下,儿改十行"的刺激生活
  3. 多态是继承の免死金牌——当你要召唤"虚函数"神龙时,该认爹还得认

总结陈词

  • 继承像结婚——高风险高回报,且行且珍惜
  • 组合像恋爱——合则来不合则换,自由无负担
  • 记住:代码不是血缘关系,少继承,多组合,你的头发会感谢你

6.总结

        本文到这里也就结束喽,今天我们完成了继承的全部内容的讲解,下面我简单的总结一下本文讲解的内容。

本章节の知识点爆米花
  1. 默认成员函数:四个"祖传家产"(构造/拷贝/析构/赋值),教你如何打造C++界的丁克家族(final大法)
  2. 继承与友元:塑料兄弟情——基类友元不会遗传,就像你爹的兄弟不会给你压岁钱!
  3. 静态成员:全家族共享的祖传充电宝(static),一人改参数,全家炸电路
  4. 多继承:修罗场の生存指南——内存布局叠罗汉,菱形继承精分现场,虚继承公证处の骚操作
  5. 组合vs继承:认爹不如雇工具人(has-a),代码界的乐高哲学——宁可多拼积木,少背族谱
前方高能预警

        你以为继承的狗血剧这就结束了?Too young!下一章我们将迎来面向对象三幻神の最终形态——多态

届时您将看到:

  • 虚函数:C++版的"我变秃了也变强了"
  • 动态绑定:运行时の分身术,让对象学会影流之主の秘技
  • 纯虚函数:抽象类の"画饼大法",堪比老板的年终奖承诺
  • 多态の黑暗面:虚表指针の内存迷踪,性能刺客の背刺警告

(剧透小剧场)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 打工人 {
public:
    virtual void 摸鱼() = 0; // 老板:这是纯虚函数,你必须实现!
};class 程序员 : public 打工人 {
public:
    void 摸鱼() override { 
        cout << "在GitHub刷绿格子" << endl; // 老板:这TM也算工作?!
    }
};
};

        准备好迎接"一个接口,千种姿势"的神奇世界了吗?下期我们将用多态实现:同一行代码,白天当社畜,晚上变蝙蝠侠的魔法操作!(≧∇≦)ノ

        各位大佬下篇文章见啦!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【玩转腾讯云】用eclipse跑通腾讯云JavaSDK
https://www.oracle.com/java/technologies/javase-jdk13-downloads.html
大大大黑白格子
2020/03/27
16.8K0
【玩转腾讯云】用eclipse跑通腾讯云JavaSDK
在Mac电脑上用VMware Fusion安装Windows7虚拟机
链接: https://pan.baidu.com/s/1Ov033tnnYl-LoQcJrpU8DA
Action
2021/03/26
3.9K0
在Mac电脑上用VMware Fusion安装Windows7虚拟机
Windows下安装Mycat
已管理员身份启动cmd,进入D:\mycat\bin目录,执行mycat install
Action
2021/09/18
2.1K0
【玩转腾讯云】我在腾讯云从域名申请到网站备案的操作攻略
最近因为工作需要开发一款微信小程序,在小程序中要发起http请求的话必要在微信小程序管理后台配置可信域名,微信对域名有2点核心的要求:带https的域名和已经ICP备案的域名。公司资源有限给不到啥支持,想起来我在腾讯云上有个域名一直闲置,于是打算拿这个域名下手。
HOHO
2021/04/23
30.4K4
【玩转腾讯云】我在腾讯云从域名申请到网站备案的操作攻略
若依前后台框架,下载运行,若依系统生成代码
1、前置工具安装 jdk 1.8 redis (缓存数据库) mysql idea (后端开发工具) nodejs (js前端开发平台,本文主要用到包管理工具 npm) vscode (前端开发工具) git (版本管理工具) 下载 [https://gitee.com/y\_project/RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) 2、运作方式 [image.png] 3、后台导入,设置 [image.png] [image.png] [image
用户7957495
2021/08/09
1.6K0
若依前后台框架,下载运行,若依系统生成代码
【5分钟玩转Lighthouse】搭建bitwardenrs一个好玩的密码网站
可参考这篇文章:轻量应用服务器 使用远程登录软件登录 Linux 实例-操作指南-文档中心-腾讯云-腾讯云 (tencent.com)
用户9673240
2022/05/05
1.2K0
【5分钟玩转Lighthouse】搭建bitwardenrs一个好玩的密码网站
Android模仿微博的LazyFragment懒加载
本文会从头开始一步一步带你去写一个LazyFragment,根据写的过程中一步一步记录,你也可以自己试一试,跟着一起写写。最后也根据遇到的问题去完善了,网上搜的都是不完善的,还是自己写一个吧!
分你一些日落
2021/12/08
4890
Android模仿微博的LazyFragment懒加载
protobuf编译、安装和简单使用C++(Windows+VS平台)
将刚才编译后的libprotobufd.lib和protoc.exe拷贝到自己创建的项目下,按住shift+右键,选择打开CMD,输入protoc --cpp_out=./ Account.proto,发现目录中多了两个文件,一个.h头文件一个.cc源文件
WindSun
2020/03/21
9.1K2
Windows下安装MongoDB
下一步安装 "install mongoDB compass" 不勾选(当然你也可以选择安装它,可能需要更久的安装时间),MongoDB Compass 是一个图形界面管理工具,我们可以在后面自己到官网下载安装,下载地址:https://www.mongodb.com/download-center/compass。
Action
2021/09/14
1K0
PHPStudy + VSCode 进行 PHP 断点调试
文件->首选项->设置->扩展->php->validate:executable path
Action
2021/08/12
2.2K0
PHPStudy + VSCode 进行 PHP 断点调试
重磅!腾讯云轻量应用服务器免费升配又双叒来了!
首先前往轻量应用服务器控制台查看机型https://console.cloud.tencent.com/lighthouse/instance/
小宇-xiaoyu
2022/03/04
3.4K0
Ichunqiu云境 - Delegation Writeup
0x1 Info图片0x2 ReconTarget external IP39.98.34.149Nmap results图片关注80端口的http服务,目录爆破(省略)找到 /admin 图片使用弱口令登录进入后台,去到模板页面,编辑header.html,添加php一句话`用户名: admin, 密码:123456![f71dd2cf6322f6235561582fe3698a6.png](https://ask8088-private-1251520898.cn-south.myqcloud.com/
Gcow安全团队
2022/12/10
4930
【玩转Lighthouse】搭建PhotoPrism开源智能相册——支持人脸识别和主题分类
PhotoPrism是一个基于Go编写的开源智能相册程序,凭借Go语言本身性能高效的特点,在实际使用中速度与稳定性远超同配置下使用PHP编写的老牌相册管理软件Piwigo。且PhotoPrism内嵌Google TensorFlow机器学习引擎,实现了类似Google Photo和群晖Moments之类的人脸识别和主题分类的功能。PhotoPrism支持多维度的照片管理,如基于地图位置、时间、自动识别的标签、人脸等,同时支持webdav服务端,方便各种移动app同步备份。
LittlePri
2022/04/15
7.6K0
竞技世界面试官:说一下公平锁和非公平锁的区别?
上次我们提到了乐观锁和悲观锁,那我们知道锁的类型还有很多种,我们今天简单聊一下,公平锁和非公平锁两口子,以及他们在我们代码中的实践。
Java程序猿
2021/07/18
3960
excel 的条件格式(二)
使用条件格式中的数据条可以非常方便地对一定区域内的单元格的数值进行可视化。照着以下步骤执行,便可以添加数据条。
mr.songw
2021/02/04
1.5K0
excel 的条件格式(二)
MySQL 索引(中)
聚簇索引是按照每张表的主键构造的一棵 B+ 树,叶子节点中存放的即为整张表的行记录数据,聚簇索引的叶子节点也称为数据页。非聚簇索引叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含一个书签。该书签用来告诉 InnoDB 存储引擎哪里可以找到与索引相对应的行数据。由于 InnoDB 存储引擎表是索引组织表,因此 InnoDB 存储引擎的非聚簇索引的书签就是相应的行数据的聚簇索引键。那么基于聚簇索引和非聚簇索引的查询的区别在哪里呢?先通过一个例子来直观感受下:查询 emp_no 为 401060 的记录,通过字段 emp_no 来查询,sql 如下。
mr.songw
2021/01/15
1.6K0
MySQL 索引(中)
2021年度Leetcode算法类型高频题总结&(附答案解析)
昨晚逛了逛GitHub,无意中看到一位P8大佬的算法刷题笔记,感觉发现了宝藏!有些小伙伴可能已经发现了,但咱这里还是忍不住安利一波,怕有些小伙伴没有看到。
Java程序猿
2021/12/24
9640
2021年度Leetcode算法类型高频题总结&(附答案解析)
基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway 报文设计 (二)
上一篇我们提到,常用的SIP 信令有:1注册、2振铃、3呼叫、4接听、5挂断、6取消
qzlink.com
2020/07/01
1.1K0
k8s的持续集成(jenkins+gitlab+k8s)
root@k8s-master1 docker.yml# kubectl get node
不凡
2021/08/19
3.9K1
【玩转Lighthouse】关于Docker部署分布式Minio的探索
根据官方文档所说,Minio分布式部署需要最低四块硬盘,也就是说利用Docker进行分布式部署的最低要求是两节点两硬盘,此次部署的计划便是如此。
SakuraRain
2022/04/22
2.5K0
推荐阅读
相关推荐
【玩转腾讯云】用eclipse跑通腾讯云JavaSDK
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验