【C++】知识点汇总(下)

C++知识点复习下

  • 一、面向对象编程:深入理解类与对象
    • 1.类的定义和访问
    • 2.this指针
    • 3.构造函数与析构函数
    • 4.重载和拷贝构造函数
    • 5.常成员和静态成员
    • 6.友元
  • 二、运算符重载
    • 1. 规则
    • 2. 成员或友元重载
      • 2.1 例子:成员函数重载
      • 2.2 例子:友元函数重载
    • 3. 类类型转换
      • 3.1 构造函数类类型转换
      • 3.2 转换运算符类类型转换
  • 三、继承
    • 1. 类之间的访问控制
      • 1.1 公有继承
      • 1.2 私有继承
      • 1.3 保护继承
    • 2. 基类初始化
    • 3. 多继承
    • 4. 虚继承
  • 四、虚函数与多态性
    • 1. 引言
    • 2. 虚函数的概念
    • 3. 静态联编与动态联编
      • 3.1 静态联编
      • 3.2 动态联编
    • 4. 类指针与多态性
    • 5. 纯虚函数与抽象类
      • 5.1 纯虚函数
      • 5.2 抽象类
  • 五、模板
    • 1. 引言
    • 2. 函数模板
    • 3. 类模板
    • 4. 模板重载

一、面向对象编程:深入理解类与对象

在面向对象编程(Object-Oriented Programming,简称OOP)中,类与对象是基本概念,对于理解和设计复杂的软件系统至关重要。包括类的定义和访问、this指针、构造函数、析构函数、重载和拷贝构造函数、常成员和静态成员以及友元。

1.类的定义和访问

在C++中,类是一种用户自定义的数据类型,用于封装数据和相关操作。以下是一个简单的类的定义和对象的访问的示例:

// 类的定义
class Person {
public:// 成员变量string name;int age;// 成员函数void displayInfo() {cout << "Name: " << name << ", Age: " << age << endl;}
};// 对象的访问
int main() {// 创建对象Person person1;// 访问对象的成员person1.name = "John";person1.age = 25;person1.displayInfo();return 0;
}

2.this指针

在类的成员函数中,this指针用于指向当前对象的地址,以便访问对象的成员。这在类的方法中经常用于区分成员变量和参数变量。

class Point {
private:int x, y;public:void setCoordinates(int x, int y) {// 使用this指针来区分成员变量和参数变量this->x = x;this->y = y;}
};

3.构造函数与析构函数

构造函数在对象创建时调用,用于初始化对象的成员变量。析构函数在对象销毁时调用,用于清理资源。以下是一个简单的例子:

class Car {
public:// 构造函数Car() {cout << "Car is created." << endl;}// 析构函数~Car() {cout << "Car is destroyed." << endl;}
};

4.重载和拷贝构造函数

重载允许在同一作用域中定义多个相同名称的函数,但参数列表不同。拷贝构造函数用于在对象创建时从另一个对象中拷贝值。

class Complex {
public:// 重载构造函数Complex(int real, int imag) {this->real = real;this->imag = imag;}// 拷贝构造函数Complex(const Complex &obj) {real = obj.real;imag = obj.imag;}private:int real, imag;
};

5.常成员和静态成员

常成员是指在成员函数中不能修改成员变量的成员,通过关键字const实现。静态成员是类的所有对象共享的成员。

class Circle {
public:// 静态成员static int count;// 常成员函数void displayRadius() const {// 不可修改成员变量// radius = 5;  // 错误cout << "Radius: " << radius << endl;}private:int radius;
};// 初始化静态成员
int Circle::count = 0;

6.友元

友元允许一个外部类或函数访问另一个类的私有成员。这提供了灵活性,但也要慎用,因为可能破坏封装性。

class Square;class Rectangle {
private:int length, width;public:Rectangle(int l, int w) : length(l), width(w) {}// 友元函数friend bool isSquare(Rectangle, Square);
};class Square {
private:int side;public:Square(int s) : side(s) {}// 友元函数的实现friend bool isSquare(Rectangle, Square);
};// 友元函数
bool isSquare(Rectangle r, Square s) {return (r.length == s.side) && (r.width == s.side);
}

二、运算符重载

1. 规则

在C++中,运算符重载必须遵循一些规则,以确保正确和一致的行为。

  1. 重载的运算符必须至少有一个操作数是用户定义的类型。
  2. 不能改变运算符的优先级或结合性。
  3. 不能创建新的运算符。
  4. 只能重载已存在的运算符。
  5. 不能改变运算符的含义。

2. 成员或友元重载

运算符重载可以通过成员函数或友元函数来实现。对于成员函数重载,通常将运算符重载作为类的成员函数,这样它至少有一个操作数是调用对象。对于友元函数,它可以访问类的私有成员,但不是类的成员。

2.1 例子:成员函数重载

class Complex {
public:Complex operator+(const Complex& other) const {Complex result;result.real = this->real + other.real;result.imaginary = this->imaginary + other.imaginary;return result;}private:double real;double imaginary;
}

2.2 例子:友元函数重载

class Complex {
public:friend Complex operator+(const Complex& c1, const Complex& c2) {Complex result;result.real = c1.real + c2.real;result.imaginary = c1.imaginary + c2.imaginary;return result;}private:double real;double imaginary;
}

3. 类类型转换

类类型转换是将一个类类型转换为另一个类类型的过程。在C++中,有两种类类型转换:构造函数和转换运算符。

3.1 构造函数类类型转换

class Distance {
public:Distance(int meters) : meters(meters) {}private:int meters;
};class Speed {
public:Speed(const Distance& distance) {// Conversion logic from distance to speed}private:// Other members
};

3.2 转换运算符类类型转换

class Rational {
public:operator double() const {return static_cast<double>(numerator) / denominator;}private:int numerator;int denominator;
}

三、继承

1. 类之间的访问控制

在C++中,继承提供了三种访问控制方式:公有继承、私有继承和保护继承。这些方式决定了派生类如何访问基类的成员。

1.1 公有继承

公有继承是最常见的一种方式,它允许派生类访问基类的公有成员,但不能访问基类的私有成员。

class Base {
public:int publicMember;
private:int privateMember;
};class Derived : public Base {// 可以访问publicMember,但不能访问privateMember
};

1.2 私有继承

私有继承使得基类的公有和保护成员在派生类中变为私有成员,因此不能被外部访问。

class Base {
public:int publicMember;
protected:int protectedMember;
};class Derived : private Base {// publicMember和protectedMember在Derived中都变成私有成员
};

1.3 保护继承

保护继承允许派生类访问基类的公有和保护成员,但它们在派生类中仍然是保护成员。

class Base {
public:int publicMember;
protected:int protectedMember;
};class Derived : protected Base {// 可以访问publicMember和protectedMember
};

2. 基类初始化

在派生类的构造函数中,需要正确初始化基类的部分。这可以通过使用初始化列表来完成。

class Base {
public:Base(int value) : data(value) {}
private:int data;
};class Derived : public Base {
public:Derived(int value) : Base(value), derivedData(value * 2) {}
private:int derivedData;
};

3. 多继承

多继承允许一个派生类同时继承多个基类。在多继承中,需要注意解决潜在的命名冲突问题。

class Base1 {
public:void display() { /* 实现 */ }
};class Base2 {
public:void display() { /* 实现 */ }
};class Derived : public Base1, public Base2 {
public:// 需要解决display()的命名冲突using Base1::display;
};

4. 虚继承

虚继承用于解决菱形继承问题,其中一个派生类通过两个不同的路径继承同一个基类。使用虚继承可以确保只有一份基类的实例。

class Base {
public:int data;
};class Derived1 : virtual public Base {// 实现
};class Derived2 : virtual public Base {// 实现
};class DiamondDerived : public Derived1, public Derived2 {// 只有一份Base的实例
};

四、虚函数与多态性

1. 引言

在面向对象的程序设计中,虚函数和多态性是C++中强大而灵活的特性。它们使得代码更加可维护、可扩展,并提高了代码的复用性。多态性的实现方式,包括静态联编、类指针、动态联编、纯虚函数和抽象类。

2. 虚函数的概念

在C++中,虚函数通过将关键字virtual添加到基类函数声明中来实现。虚函数的存在使得在运行时能够根据对象的实际类型调用相应的函数。

class Shape {
public:virtual void draw() {// 基类中的虚函数// 具体实现由派生类提供}
};

3. 静态联编与动态联编

3.1 静态联编

静态联编是指在编译时确定调用哪个函数,这是C++中默认的行为。对于非虚函数,编译器在编译时就能确定要调用的函数。

class Base {
public:void print() {std::cout << "Base class" << std::endl;}
};class Derived : public Base {
public:void print() {std::cout << "Derived class" << std::endl;}
};int main() {Derived derivedObj;derivedObj.print();  // 编译时确定调用Derived::print()return 0;
}

3.2 动态联编

动态联编是通过使用虚函数来实现的,它允许在运行时确定要调用的函数。使用基类指针或引用调用虚函数会触发动态联编。

int main() {Base* basePtr = new Derived();basePtr->print();  // 运行时确定调用Derived::print()delete basePtr;return 0;
}

4. 类指针与多态性

通过使用基类指针或引用,可以实现对派生类对象的多态操作。

void drawShape(Shape* shape) {shape->draw();  // 调用派生类中相应的draw函数
}int main() {Circle circle;Square square;drawShape(&circle);  // 多态调用Circle::draw()drawShape(&square);  // 多态调用Square::draw()return 0;
}

5. 纯虚函数与抽象类

5.1 纯虚函数

纯虚函数是在基类中声明的虚函数,但没有提供具体实现。包含纯虚函数的类被称为抽象类。

class AbstractShape {
public:virtual void draw() = 0;  // 纯虚函数
};class ConcreteShape : public AbstractShape {
public:void draw() override {// 具体实现}
};

5.2 抽象类

抽象类不能实例化,但可以作为接口类,定义派生类必须实现的接口。

void drawAllShapes(std::vector<AbstractShape*>& shapes) {for (auto shape : shapes) {shape->draw();  // 多态调用各个派生类的draw函数}
}int main() {Circle circle;Square square;ConcreteShape concreteShape;std::vector<AbstractShape*> shapes = {&circle, &square, &concreteShape};drawAllShapes(shapes);return 0;
}

五、模板

1. 引言

C++模板是一种强大的编程工具,它允许在编写代码时使用泛型类型。泛型编程使得代码更加灵活和可重用,因为它允许编写与特定数据类型无关的通用代码。在C++中,主要有两种类型的模板:函数模板和类模板。此外,C++还支持模板的重载,使得我们可以根据不同的需求定义多个模板版本。

2. 函数模板

函数模板是一种允许定义通用函数的机制,可以处理不同类型的参数。下面是一个简单的函数模板示例:

template <typename T>
T add(T a, T b) {return a + b;
}int main() {int result_int = add(5, 10);double result_double = add(3.5, 2.7);return 0;
}

在上面的例子中,add 函数是一个模板函数,可以处理不同类型的参数,包括整数和浮点数。

3. 类模板

类模板允许我们定义通用类,可以处理不同类型的数据。以下是一个简单的类模板示例:

template <typename T>
class Pair {
public:Pair(T first, T second) : first_(first), second_(second) {}T getFirst() const {return first_;}T getSecond() const {return second_;}private:T first_;T second_;
};int main() {Pair<int> intPair(1, 2);Pair<double> doublePair(3.5, 2.7);return 0;
}

在这个例子中,Pair 类模板可以处理不同类型的数据,例如 intdouble

4. 模板重载

模板重载允许我们定义多个模板版本以处理不同类型或不同数量的参数。以下是一个模板重载的示例:

template <typename T>
T multiply(T a, T b) {return a * b;
}template <typename T, typename U>
U multiply(T a, U b) {return a * b;
}int main() {int result1 = multiply(5, 10);double result2 = multiply(3.5, 2.7);return 0;
}

在这个例子中,有两个版本的 multiply 函数,分别处理相同类型和不同类型的参数。

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

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

相关文章

how2heap-2.23-03-fastbin_dup_consolidate

#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h>int main() {void* p1 malloc(0x10);strcpy(p1, "AAAAAAAA");void* p2 malloc(0x10);strcpy(p2, "BBBBBBBB");fprintf(stderr, "申请两个…

手机怎么边看视频边记笔记或备忘录?

在这个信息爆炸的时代&#xff0c;我们经常需要通过看培训视频、听网课来不断充实自己。但是&#xff0c;手机屏幕那么小&#xff0c;如何才能在做笔记的同时&#xff0c;又不错过视频的每一个细节呢&#xff1f; 以前&#xff0c;我总是为此头疼。一手拿着手机看视频&#xf…

【嵌入式】About USB Powering

https://www.embedded.com/usb-type-c-and-power-delivery-101-power-delivery-protocol/https://www.embedded.com/usb-type-c-and-power-delivery-101-power-delivery-protocol/ Type-C接口有多强&#xff1f;PD协议又是什么&#xff1f;-电子发烧友网由于Type-C接口自身的强…

网站报错:nginx 413 Request Entity Too Large

问题描述 我在上传一个图片文件的时候&#xff0c;收到 Nginx 报错&#xff1a; 413 Request Entity Too Large 问题原因 Nginx 默认上传文件大小是 1 MB&#xff0c;如果上传过大文件&#xff0c;会报上面的错误。 解决方法 需要修改nginx的配置文件。以下是如何修改的步…

c++牛客总结

一、c/c语言基础 1、基础 1、指针和引用的区别 指针是一个新的变量&#xff0c;指向另一个变量的地址&#xff0c;我们可以通过这个地址来修改该另一个变量&#xff1b; 引用是一个别名&#xff0c;对引用的操作就是对变量本身进行操作&#xff1b;指针可以有多级 引用只有一…

【QT】return 和 break 是 C++ 中两个不同的关键字,它们在程序中有不同的用途。

return 和 break &#xff1a; return&#xff1a; 用于从函数中返回值&#xff0c;结束函数的执行&#xff0c;并将控制返回到调用函数的地方。在函数体中&#xff0c;当执行到 return 语句时&#xff0c;函数将立即退出&#xff0c;不再执行后续的语句。可以带有一个值&#…

2024年软考什么时候报名?一年考几次?

2024年上半年报名时间预计在3月中上旬开始&#xff0c;考试时间预计为5月25日。 报考条件及报名流程 报考条件&#xff1a; 1.遵守中华人民共和国宪法和各项法律&#xff0c;恪守职业道德&#xff0c;具有一定计算机技术应用能力的人员&#xff0c;均可根据本人情况报名参加…

【学生特惠|权威主办】2024年地理科学与遥感技术国际学术会议(ICGSRST 2024)

【学生特惠|权威主办】2024年地理科学与遥感技术国际学术会议(ICGSRST 2024) 2024 International Conference Geographic Science and Remote Sensing Technology(ICGSRST 2024) 一、【会议简介】 我们非常荣幸地邀请您参加2024年地理科学与遥感技术国际学术会议&#xff08;I…

Linux Perf 介绍

文章目录 前言 二、安装Perf三、二级命令3.1 perf list3.2 perf record/report3.3 perf stat3.4 perf top 四、使用火焰图进行性能分析4.1 下载火焰图可视化生成器4.2 使用perf采集数据4.3 生成火焰图参考资料 前言 perf是一款Linux性能分析工具&#xff0c;内置在Linux内核的…

第一讲_css三种编写方式

css三种编写方式 1. 行内样式2. 内部样式3. 外部样式3.1 编写css文件3.2 引入css文件 4. 三种方式的优先级 1. 行内样式 在标签的style属性中设置样式&#xff0c;多个样式属性之间用;隔开。 <html><div style"color: #000000; font-size: 50px">行内样…

使用XMLHttpRequest判断浏览器地址栏有没有访问成功

以下是使用XMLHttpRequest对象实现判断http://127.0.0.1:8080/index地址是否访问成功的示例代码&#xff1a; var xhr new XMLHttpRequest(); xhr.open(GET, http://127.0.0.1:8080/index); xhr.onreadystatechange function() {if (xhr.readyState 4) { // 请求完成if (xh…

virtualbox新建Ubuntu虚拟机

1、下载virtualbox 2、下载Ubuntu镜像 https://ubuntu.com/blog/desktop virtualbox安装好后&#xff0c;点击新建 选择linux类型 选择内存2~4G都行 选择先不添加虚拟硬盘 创建硬盘&#xff0c;管理点击虚拟介质管理 点击创建&#xff0c;选择创建类型为vmdk&#xff0…

xshell配色

xshell-设置命令行提示符&配色方案 更换配色&#xff1a; Protect Eyes.xcs [Protect Eyes] text00ff40 cyan(bold)93a1a1 text(bold)839496 magentadd3682 green80ff80 green(bold)859900 background042028 cyan2aa198 red(bold)cb4b16 yellowb58900 magenta(bold)6c71c…

腾讯云Centos9使用docker的方式安装APISIX

在虚拟机中安装Docker、Docker-compose 安装Docker 清除旧版本的docker yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 安装docker的依赖 yum install -y yum-utils device-ma…

Android 实现动态申请各项权限

在Android应用中&#xff0c;如果需要使用一些敏感的权限&#xff08;例如相机、位置等&#xff09;&#xff0c;需要经过用户的授权才能访问。在Android 6.0&#xff08;API级别23&#xff09;及以上的版本中&#xff0c;引入了动态权限申请机制。以下是在Android应用中实现动…

Linux下QT生成的(.o)、(.a)、(.so)、(.so.1)、(.so.1.0)、(.so.1.0.0)之间的区别

记录一下&#xff1a;Linux系统下编译动态库会生成多个.so文件 &#xff08;1&#xff09;Linux 下 QT 生成的&#xff08;.o&#xff09;、&#xff08;.a&#xff09;和&#xff08;.so&#xff09;三个文件的区别 &#xff08;.o&#xff09;就相当于windows里的obj文件&…

腾讯云域名外部入库流程

注册商是腾讯云&#xff0c;且在腾讯云管理的&#xff0c;请使用此教程外部入库。 如您的域名注册商是腾讯云但在聚名管理&#xff0c;请参考教程&#xff1a;https://www.west.cn/faq/list.asp?unid2539 在外部入库操作之前&#xff0c;请先登录腾讯云获取账号ID信息。…

CCF-B类 | 持续中科院1区TOP,Elsevier出版社,50年老刊!

【SciencePub学术】本期&#xff0c;小编给大家推荐的是一本Elsevier旗下&#xff0c;CCF-B类&#xff0c;影响因子为8.0的中科院1区TOP。其详情如下&#xff1a; 期刊简介 PATTERN RECOGNITION ISSN&#xff1a;0031-3203 E-ISSN&#xff1a;1873-5142 IF&#xff08;20…

使用Go语言编写高效的HTTP服务器

随着互联网的快速发展&#xff0c;HTTP服务器在Web开发中扮演着越来越重要的角色。而Go语言作为一种高效、并发性强的编程语言&#xff0c;为编写高性能的HTTP服务器提供了强大的支持。本文将探讨如何使用Go语言编写高效的HTTP服务器。 首先&#xff0c;我们需要了解Go语言的H…

Keras常用的激活函数详细介绍

在Keras中&#xff0c;常用的激活函数包括以下几种&#xff0c;我将为您详细介绍它们&#xff1a; 线性激活函数 (Linear)&#xff1a; 公式&#xff1a;(f(x) x)特点&#xff1a;线性激活函数实际上不对输入进行任何改变&#xff0c;它直接输出输入值。这通常在回归问题或神…