当前位置: 首页 > news >正文

C++高频知识点(九)

文章目录

  • 41. 如何区分一段代码是C++还是C代码编写的
  • 42. 说一下C++的返回值优化
  • 43. C++中为什么用类模板
  • 44. 子类不能继承父类的函数有哪些
  • 45. 谈谈stl标准库的线程安全性

41. 如何区分一段代码是C++还是C代码编写的

区分一段代码是用C++还是C编写的,可以通过以下几个方面来判断:
1. 文件扩展名

  • C代码:通常使用.c作为文件扩展名。
  • C++代码:通常使用.cpp、.cc、.cxx、.C等作为文件扩展名。

2. 语言特性和语法
变量声明和定义

  • C:变量必须在块的开头声明

C99 标准及后续版本
从 C99 标准(1999 年发布)开始,C 语言变得更加灵活,允许变量在 块的任何位置 声明。也就是说,变量可以在它们第一次使用之前声明,而不必放在函数体的开头。这个变化使得代码更加灵活和易于理解。

#include <stdio.h>int main() {int a = 10;a = a + 1; // 可执行语句int b = 20; // 非法:变量声明在可执行语句之后return 0;
}

在这里插入图片描述
在这里插入图片描述
C++:支持类和对象,包含继承、多态等特性。

class Point {
public:int x;int y;Point(int x, int y) : x(x), y(y) {}void display() {std::cout << x << ", " << y << std::endl;}
};

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

42. 说一下C++的返回值优化

在这里插入图片描述
考虑以下的简单示例,演示了返回值优化的作用:

#include <iostream>// 定义一个简单的类
class MyClass {
public:// 默认构造函数MyClass() { std::cout << "Default Constructor\n"; }// 拷贝构造函数MyClass(const MyClass& other) { std::cout << "Copy Constructor\n"; }// 移动构造函数MyClass(MyClass&& other) noexcept { std::cout << "Move Constructor\n"; }
};// 返回一个对象的函数
MyClass createObject() {return MyClass();
}int main() {MyClass obj = createObject();return 0;
}

在上述示例中,createObject() 函数返回一个 MyClass 对象。根据返回值优化的原理,编译器可能会直接将这个对象构造在 main() 函数中的 obj 变量所在的空间中,而不需要额外的拷贝构造函数调用。如果编译器执行了返回值优化,输出将会是:
在这里插入图片描述
而不会输出额外的 “Copy Constructor”。这是因为编译器可以优化,避免了将临时对象复制给 obj 的过程,而是直接在 obj 的位置构造了该对象。

在这里插入图片描述

43. C++中为什么用类模板

在这里插入图片描述
5. 标准库支持:C++标准库中大量使用了模板类,例如容器类(如vector、list)、算法(如sort、find)等,这些模板类为C++程序员提供了强大且高效的工具。

示例:(如果不用模板 需要分别指定类型)

// 示例:模板类实现一个通用的堆栈数据结构
template <typename T>
class Stack {
private:std::vector<T> elements;public:void push(const T& element) {elements.push_back(element);}T pop() {if (elements.empty()) {throw std::out_of_range("Stack<>::pop(): empty stack");}T element = elements.back();elements.pop_back();return element;}bool empty() const {return elements.empty();}
};int main() {Stack<int> intStack;intStack.push(10);intStack.push(20);intStack.push(30);while (!intStack.empty()) {std::cout << intStack.pop() << " ";}std::cout << std::endl;Stack<std::string> stringStack;stringStack.push("Hello");stringStack.push("World");while (!stringStack.empty()) {std::cout << stringStack.pop() << " ";}std::cout << std::endl;return 0;
}

在上述示例中,Stack 是一个模板类,可以用于存储不同类型的元素,如整数和字符串,同时保持相同的堆栈操作接口。这种灵活性和通用性使得模板类在现代C++编程中非常重要和常用。

44. 子类不能继承父类的函数有哪些

在C++中,子类(派生类)无法继承父类(基类)的以下内容:
在这里插入图片描述
2. 构造函数和析构函数:虽然构造函数和析构函数实际上是可以继承的,但它们不会被子类继承并且不会直接调用。子类需要自己定义构造函数和析构函数来初始化和清理自己的成员。

class Base {
public:Base() {}~Base() {}
};class Derived : public Base {// Derived 有一个默认构造函数和析构函数,// 但它们不会继承 Base 的构造函数和析构函数
};

3. 父类中被子类重载的函数:如果子类重新定义了父类的同名函数(重载),则父类中该函数的其他版本对子类是不可见的。

class Base {
public:void someFunction() {}
};class Derived : public Base {
public:void someFunction(int value) {}// Derived 中的 someFunction 重载了 Base 中的 someFunction,// Base 中的 void someFunction() 对 Derived 不可见
};

4. 静态成员函数和静态成员变量:子类可以继承父类的静态成员(也就是说可用,但不算继承),但不能直接继承父类的静态成员函数或静态成员变量。子类可以通过父类名字限定符来访问父类的静态成员,但这并不算继承。

class Base {
public:static void staticFunction() {}static int staticVariable;
};int Base::staticVariable = 0;class Derived : public Base {
};// Derived 无法直接调用或继承 Base 的 staticFunction 和 staticVariable

5. 友元函数:如果父类声明了一个友元函数,子类并不会继承该友元函数的访问权限,除非子类也被声明为友元类。

class Base {friend void friendFunction();
};void friendFunction() {Base b;// 可以访问 Base 的私有成员,但 Derived 无法继承 friendFunction 的友元权限
}class Derived : public Base {// Derived 无法访问 friendFunction,也不会继承其友元权限
};

6. 虚函数的具体化:如果在父类中使用了 final 关键字,表示虚函数不可被子类重写。这意味着子类不能继承并重写这些具体化的虚函数。

class Base {
public:virtual void finalFunction() final {}
};class Derived : public Base {// Derived 无法继承并重写 Base 中被 final 修饰的 finalFunction
};

45. 谈谈stl标准库的线程安全性

在这里插入图片描述
在这里插入图片描述

#include <mutex>
#include <vector>std::vector<int> vec;
std::mutex mtx;// 线程安全地向 vec 中添加元素
void addToVector(int value) {std::lock_guard<std::mutex> lock(mtx);vec.push_back(value);
}

在这里插入图片描述
在这里插入图片描述

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

http://www.lryc.cn/news/587239.html

相关文章:

  • 39.Sentinel微服务流量控制组件
  • 【一起来学AI大模型】部署优化推理加速:vLLM
  • word中多行合一功能实现
  • comfyUI-ControlNet-姿势控制深度控制
  • Java 8 LocalDate 日期操作全攻略
  • CS课程项目设计1:交互友好的井字棋游戏
  • 【多线程】 线程池设多大才合理?CPU 密集型和 I/O 密集型的终极公式
  • 深度学习图像分类数据集—七种树叶识别分类
  • AI生成单词消消乐游戏. HTML代码
  • LeetCode 2401.最长优雅子数组
  • Ampace厦门新能安科技Verify 测评演绎数字推理及四色测评考点分析、SHL真题题库
  • 【sql学习之拉链表】
  • 系规备考论文:论IT服务知识管理
  • MyBatis框架进阶指南:深入理解CRUD与参数映射
  • CVE-2022-0609
  • Oracle SQL - 使用行转列PIVOT减少表重复扫描(实例)
  • 常用的docker命令备份
  • Docker从环境配置到应用上云的极简路径
  • 《Google 软件工程》:如何写好文档?
  • Qt窗口:QToolBar、QStatusBar、QDockWidget、QDialog
  • QT 多线程 管理串口
  • Vue框架之计算属性与侦听器详解
  • 深入理解 LangChain:AI 应用开发的全新范式
  • openEuler欧拉系统重置密码
  • 标注识别 自己的数据集20张 roboflow 实例分割
  • 基于requests_html的爬虫实战
  • 【DVWA系列】——File Upload——low详细教程(webshell工具冰蝎)
  • Vue Router 完全指南:从入门到实战,高效管理前端路由
  • 12.I/O复用
  • 光盘处理难题不用愁,DVDFab 来救场