中级C ++教程:字符串,映射,内存等

作者 : IT 大叔 本文共7162个字,预计阅读时间需要18分钟 发布时间: 2020-08-14

中级C ++教程:字符串,映射,内存等插图

C ++是最早的编程语言之一,创建于1979年。由于它在视频游戏开发,操作系统,浏览器以及办公和医疗软件等领域的大型系统性能中使用,它一直是现代开发人员的重要语言。该语言的使用不断增加,目前已被新兴技术(如VR和自动驾驶汽车)采用。

很容易看出为什么开发人员对学习这种语言感兴趣。如果您已经在学习C ++,您可能已经注意到,由于其严格的语法和对堆内存使用之类的手动管理要求,可能很难掌握C ++。

不用担心!C ++仍然是一种很有价值的语言,因此,今天我们将带您逐步了解一些C ++的中级概念和示例,以使您更进一步地掌握这一具有挑战性但广受欢迎的语言。为了使本文最成功,您应该已经具有C ++语法的一些基础知识。

以下是我们今天将讨论的主题:

  • 在C ++中使用面向对象的编程
  • 字符串在C ++中如何工作?
  • C ++中的指针是什么?
  • 什么是C ++中的数组?
  • C ++中的向量是什么?
  • 使用C ++映射
  • C ++中的内存管理
  • 接下来要学什么

在C ++中使用面向对象的编程

C ++是一种面向对象的语言。此范例是其与C和C#的明显区别之一。在C ++中,我们通过使用对象和类来存储和操作数据来实现这一点。通过这种面向对象的方法,开发人员可以实现继承,多态,抽象和封装的策略。

学习C ++时,重要的是要了解如何充分利用其OOP功能。下面,我们将探讨每种核心OOP策略的一些示例:继承,多态性,抽象和封装。

在C ++中使用继承

在C ++中设置继承关系很容易。我们只需在类声明后附加即可: [parent name]()。这使我们可以从父类到子类共享公共变量和方法。

在下面,您将看到我们如何使用它来创建BankAccount类,从类中提取Account

#include <iostream>
 
class Account{
 
public:
   Account(double b): balance(b){}
 
   void deposit(double amt){
     balance += amt;
   }
 
   void withdraw(double amt){
     balance -= amt;
   }
 
   double getBalance() const {
     return balance;
   }
 
private:
   double balance;
 
};
 
class BankAccount: public Account{
 
public:
  // using Account::Account;
  BankAccount(double b): Account(b){}
 
  void addInterest(){
    deposit( getBalance()*0.05 );
  }
};
 
int main(){
 
  std::cout << std::endl;
 
  BankAccount bankAcc(100.0);
  bankAcc.deposit(50.0);
  bankAcc.deposit(25.15);
  bankAcc.withdraw(30);
  bankAcc.addInterest();
 
  std::cout << "bankAcc.getBalance(): " << bankAcc.getBalance() << std::endl;
 
  std::cout << std::endl;
 
}

上面,我们创建了两个类:parent Account和child BankAccount。我们定义的公共职能depositwithdraw以及getBalanceAccountaddInterestBankAccount

在主要部分中,我们将了解如何在新BankAccount对象上使用所有这些函数bankAcc,而不管该函数是来自父类还是子类。

在C ++中使用多态

C ++中多态性最常见的应用之一就是通过函数重写。通过在不同的类中具有两个具有相同名称的函数,我们可以创建代码,以根据所选对象的继承来完成不同的行为。

下面,我们将看到一个示例,说明如何使用多态来Draw跨不同的形状类实现示例函数:

为了专注于重写的函数,我们只为每个函数填充Draw了一个简单的唯一count语句。但是,可以用绘图算法代替它,并且行为方式相同。

class Shape
{
  public:
  Shape(){}
  //defining a virtual function called Draw for shape class 
  virtual void Draw(){cout<<"Drawing a Shape"<<endl;} 
};

class Rectangle: public Shape
{
  public:
  Rectangle(){}
  //Draw function defined for Rectangle class
  virtual void Draw(){cout<<"Drawing a Rectangle"<<endl;} 
};

class Triangle: public Shape
{
  public:
  Triangle(){}
  //Draw function defined for Triangle class
  virtual void Draw(){cout<<"Drawing a Triangle"<<endl;}
};

class Circle: public Shape
{
  public:
  Circle(){}
  //Draw function defined for Circle class
  virtual void Draw(){cout<<"Drawing a Circle"<<endl;}
};


int main() {
  
  Shape *s; 
  
  Triangle tri;
  Rectangle rec;
  Circle circ;
  
  // store the address of Rectangle
  s = &rec;
  // call Rectangle Draw function
  s->Draw();
  
  // store the address of Triangle
  s = &tri;
  // call Traingle Draw function
  s->Draw();
  
  // store the address of Circle
  s = &circ;
  // call Circle Draw function 
  s->Draw();
  
  return 0;
  
}

在上方,我们看到一个父类shape,以及两个子类TriangleRectangle。绘制每个形状的过程将根据形状本身而有所不同。这导致我们使用多态来Draw为每个类定义一个函数。

Draw默认情况下,C ++将优先于本地函数而不是父函数。这意味着我们可以调用Draw而不必担心对象是哪个形状类。如果是矩形,则输出将为“绘制矩形”。如果是三角形,则将输出“绘制三角形”。

抽象和封装

通过使用privateand public关键字,抽象在C ++中的工作方式与其他硬编码语言类似。这类似于抽象,因为抽象可隐藏非必要信息。封装可用于通过私有getter和setter函数实现抽象。

下面,我们将看到如何在C ++中实现抽象和封装:

#include <iostream>
using namespace std;
  
class abstraction
{
    private:
        int a, b;
  
    public:
     
        // public setter function
        void set(int x, int y)
        {
            a = x;
            b = y;
        }
 
        // public getter function  
        void display()
        {
            cout<<"a = " <<a << endl;
            cout<<"b = " << b << endl;
        }
};
  
int main() 
{
    abstraction obj;
 
    obj.set(1, 2);
    obj.display();
 
    return 0;
}

在这里,我们首先创建一个abstraction用于初始化私有变量a和的类b。我们还定义了两个公共函数,setdisplay。这样可以通过将变量与外界隔离来实现封装,因此我们只能通过公共函数访问它们。使用set,然后从内部更改值main。最后,我们使用来打印变量display

这样可以确保用户不能直接更改变量,而是可以通过getter和setter函数使用它们,从而通过保持变量本身的安全性并对用户隐藏来实现抽象。

字符串在C ++中如何工作?

C ++中的字符串与其他语言的字符串相似,因为它们是有序字符的集合。但是,在C ++中,有两种创建字符串的方法,即使用C样式字符串或C ++ string类。

C style strings是在C ++中创建字符串的老式方法。而不是标准的字符串对象,它C-style strings由以特殊字符结尾的以null终止的字符数组组成\0。由于此隐藏字符,C样式字符串的长度始终比可见数目的字符长一个字符。

可以不指定此大小,以自动将其设置为所需的大小,也可以手动将其设置为任何所需的大小。

char str[] = "Educative"; // automatic length set to 10
char str[10] = "Educative"; // manual set length to 10

我们还可以使用标准C ++库中string内置的C ++ 类在C ++中创建字符串。这是更流行的方法,因为所有内存管理,分配和空终止都由该类内部处理。另一个优点是,由于动态分配内存,可以在运行时更改字符串的长度。

总体而言,这些更改使string类对错误的抵抗力增强,并提供了许多内置函数,如append(),它添加到字符串的末尾length(),而则返回字符串中的字符数。

下面,我们将学习如何使用类似这样的函数来完成常见的字符串操作。

如何打印字符串

我们可以使用cout全局对象以及<<在打印内容之前的运算符在C ++中打印字符串。我们还包括endl全局对象,该对象用于在操作后跳过一行以提高可读性。由于endlcout都是全局类的预定义对象,因此ostream我们必须确保将<iostream>标头包含在需要它们的程序中。

下面我们可以看到如何初始化和打印str1

#include <iostream>
#include <string>
using namespace std;
int main() {
   string str1 ("printed string"); //initializes the string
   cout << str1 << endl;  //prints string
   return 0;
}

如何计算字符串的长度

要计算字符串的长度,我们可以使用length()size()函数。每个都执行相同,并且每个都存在以提高可读性。这些功能还可用于测量STL容器(如地图和矢量)的长度。

包括同义功能以提高可读性,因为虽然长度直观地用于字符串,但指向数组的大小要比其长度更为直观。

下面我们将看到如何str1使用lengthsize函数同时打印字符串的长度。

#include <iostream>
#include <string>
using namespace std;
 
int main() {
  string str1 = "Hello"; //initilization
  
  //calculate length
  cout << "myStr's length is " << str1.length() << endl;
  cout << "myStr's size is " << str1.size() << endl;
 
  return 0;
}

如何连接字符串

这种最终的操作是一种“将两条弦粘在一起”的奇特方式。在C ++中执行此操作时,我们可以使用+运算符或预定义append函数,它们各自可以达到相同的效果。

对于简单的测试代码,两个选项之间几乎没有区别。但是,当在更大,更复杂的程序中使用时,其append执行速度将明显高于+

#include <iostream>
#include <string>
using namespace std;
int main() {

string str1= "combined ";
string str2 = "strings";
string str3 = str1 + str2;
cout << str3 << endl;

//OR

string str4 = str1.append(str2);
cout << str4;

}

C ++中的指针是什么?

在C ++中,所有变量必须存储在主机计算机内存中的某个位置。为了帮助程序在不搜索内存的情况下找到这些变量,C ++允许我们使用特殊变量指针来显式给出变量的地址。

指针包含两个信息:

  • 存储为指针值的内存地址
  • 指示其指向的变量类型的数据类型

声明指针与声明标准变量相似,不同之处在于,指针的名称前面带有星号。

int *ptr; 
struct coord *pCrd; 
void *vp;

让我们看看如何在下面使用它:

#include <iostream>
using namespace std;

int main ()
{
  int val1, val2;
  int * mypointer;

  mypointer = &val1;
  *mypointer = 10;
  mypointer = &val2;
  *mypointer = 20;
  cout << "firstvalue is " << val1 << '\n';
  cout << "secondvalue is " << val2 << '\n';
  return 0;
}

首先,我们初始化两个int变量 val1,并且val2还有一个int指针mypointer。然后mypointer,我们将其设置为val1使用&运算符的地址。然后,mypointer指向的值设置为10。由于mypointer当前指向的地址val1,因此此操作会更改的值val1

然后,我们重复该过程,将mypointer地址设置为,val2并将该位置的值设置为20

指针在C ++中具有两个主要优点:速度和内存使用。使用指针减少了运行时间,因为当程序被赋予直接内存地址时它们可以更快地访问值。

指针备忘单

由于指针是C ++较为独特的元素之一,因此记住所有可以使用它们的技巧可能会很棘手。为了获得帮助,这是我们关于基本指针语法的快速指南:

句法 目的
int *p 声明一个指针 p
p = new int 在动态内存中创建一个整数变量,并将其地址放入 p
p = new int[5] 创建大小为5的动态数组,并将其第一个索引的地址放入 p
p = &var pvar变量
*p 访问p指向的对象的值
*p = 8 将对象的值更新p
p 访问对象的内存地址p指向

什么是C ++中的数组?

数组是以相同名称存储的相似数据类型的集合。它们通常被可视化为一排i盒子,可以通过调用盒子的索引来访问其中保存的值来选择它们。

提示:数组索引值从0开始,这意味着可以通过调用element 0而不是调用访问数组中的第一个元素1

数组的长度在声明时(显式或隐式)设置,并且如果不完全重建数组,则无法更改。但是,与向量相比,这使该数组具有很高的内存效率结构,因为在初始化数组之后不使用任何内存。

#include <iostream>
using namespace std;

int main() {
  int arr[5] = {19, 10, 5, 6, 14}; //initializing the array with 5 values
  cout << "The value of arrr[0], that is, the first value in the array is: " << arr[0] << endl;
  cout<< "The value of arrr[1], that is, the second value in the array is: " << arr[1] << endl;
  cout<< "The value of arrr[2], that is, the third value in the array is: " << arr[2] << endl;
  cout<< "The value of arrr[3], that is, the fourth value in the array is: " << arr[3] << endl;
  cout<< "The value of arrr[4], that is, the fifth value in the array is: " << arr[4] << endl;
  int arr2[] = {1,2,3,4}; //we don't specify the size and the compiler assumes a size of 4
}

如何在C ++中查找数组的长度

与STL容器和字符串不同,我们无法使用length或来找到数组的长度size。取而代之的是,我们使用sizeof()运算符或使用指针算法。

让我们看看如何使用每种方法sizeof

#include <iostream>
using namespace std;
 
int main() {
  int arr[] = {1,2,3,4,5,6};
  int arrSize = sizeof(arr)/sizeof(arr[0]);
  cout << "The size of the array is: " << arrSize;
  return 0;
}

length函数不同,它sizeof实际上返回所选对象在内存中占用的字节数。数组中每个元素的大小因数组而异,因此我们不能假定它只是一个字节。

为了解决这个问题,我们使用同一数组中的每个元素将使用相同的内存量。因此,如果我们将数组使用的总字节sizeof(arr)数除以第一个元素使用的字节数sizeof(arr[0]),则得到数组中元素的数目。

查找大小的另一种方法是使用指针算法:

#include <iostream>
using namespace std;
 
int main() {
  int arr[] = {1,2,3,4,5,6};
  int arrSize = *(&arr + 1) - arr;
  cout << "The size of the array is: " << arrSize;
  return 0;
}

如果我们认为数组的大小等于数组的最后一个元素的地址与第一个元素的地址之差,那么我们可以实现类似的效果。

这是一步一步的细分:

  • (&arr + 1) 指向数组末尾之后的内存地址。
  • (&arr + 1)只需将上述地址转换为即可int *
  • 从数组末尾的地址减去数组开头的地址,得出数组的长度。
免责声明:
1. 本站资源转自互联网,源码资源分享仅供交流学习,下载后切勿用于商业用途,否则开发者追究责任与本站无关!
2. 本站使用「署名 4.0 国际」创作协议,可自由转载、引用,但需署名原版权作者且注明文章出处
3. 未登录无法下载,登录使用金币下载所有资源。
IT小站 » 中级C ++教程:字符串,映射,内存等

常见问题FAQ

没有金币/金币不足 怎么办?
本站已开通每日签到送金币,每日签到赠送五枚金币,金币可累积。
所有资源普通会员都能下载吗?
本站所有资源普通会员都可以下载,需要消耗金币下载的白金会员资源,通过每日签到,即可获取免费金币,金币可累积使用。

发表评论