c++学习笔记(7) 面向对象思想

面向对象思想:

1.string类:

C字符串:将字符串看作以‘/0’结尾的字符数组

string类: 处理字符串

2. 使用string类对象:

// 字符串初始化
string s1 = "Welcome to c++";
string s2("welcome to c++"); //构造方法,更高效

 字符串追加函数 append()

 字符串赋值函数assign()

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
// append()函数
string s1("Welcome"); // 使用string类的构造方法初始化一个字符串
s1.append(" to c++"); // 直接追加
cout <<"s1 is: " << s1 << endl;
string s2("Welcome");
s2.append(" to C and c++", 5); // 将" to c and c++"的前五个字符追加到s2后面
cout << "s2 is: " << s2 << endl;
string s3("Welcome");
s3.append(3, 'G'); // 将字符'G'赋值为”GGG“追加到s3的后面
cout << "s3 is: " << s3 << endl;
// assign函数
string s4("Welcome");
s4.assign("Dollars"); // 给s4重新赋值
cout << "s4 is: " << s4 << endl;
string s5("Welcome");
s5.assign(5, 'F'); // 将”FFFFF“赋值给s5
cout << "s5 is: " << s5 << endl;
}

结果:

3. 函数

 at(index)   返回索引值处的字符

 clear()   清空一个字符串

bool  empty()

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
string s1("Welcome"); // 使用string类的构造方法初始化一个字符串
cout << s1.at(3) << endl;
cout << s1.erase(2, 3); // 从s1[2]处擦除3个字符 welcome-->weme
s1.clear();
cout << s1.empty() << endl;
return 0;
}

  函数

  length()    长度

  size()       大小

  capacity()    存储空间

  c_str()    返回一个C字符串

  compare()  返回值-1,1,0

  substr()  :   substr(index, n)-->从index起始的n个字符  substr(index)   返回从index起始到末尾的字符串

  find()   字符串搜索函数:

  find(ch):       返回ch第一次出现的位置

  find(sunstr)    子串出现的位置

  find(ch, index)   返回从index位置起,ch出现的位置

  find(substr,   index)

 insert(index,  s)   index位置,  s子串

 insert(index,  n, ch)   index位置,  n个字符

 replace() 

 5. 数字,字符串 相互转化

 1.  atoi(), atof(), 将字符串转化为 int 和 float

 2. itoa(int n,  char [],  2/8/10/16)   将数字转化为字符串

 3. <sstream>头文件

     stringstream类,提供的接口可以使我们像处理输入输出流一样来处理字符串

     code:

#include <iostream>
#include <string>
#include <iomanip>
#include <sstream> // 将数字转化为字符串
using namespace std;
int main(int argc, char *argv[])
{
stringstream ss; // stringstream类,提供的接口可以使我们像处理输入输出流一样;来处理字符串
ss << 3.1245;
string s1 = ss.str();
cout << s1 << endl;
cout << s1.erase(2, 2) << endl; // 3.1245-->3.45
ss << 98.45667;
string s2 = ss.str();
cout << s2.append("Welcome") << endl; // 98.45667Welcome
return 0;
}

结果:

6. 字符串分割:
使用stringstream类来完成

#include <iostream>
#include <string>
#include <iomanip>
#include <sstream> // 将数字转化为字符串
using namespace std;
int main(int argc, char *argv[])
{
string text("Programing is very fun"); // 将每一个单词提取出来
stringstream ss(text); // stringstream类,提供的接口可以使我们像处理输入输出流一样;来处理字符串
cout << "The word in text are: " << endl;
string word;
while(!ss.eof())
{
ss >> word;
cout << word << endl;
}
return 0;
}

结果:

7.字符串替换的实现:

  将字符串s中的oldSubStr替换为newStr

  代码:

#include <iostream>
#include <string>
#include <iomanip>
#include <sstream> // 将数字转化为字符串
using namespace std;
bool replaceString(string&, string&, string&);
int main(int argc, char *argv[])
{
string ss, old_string, new_string;
cin >> ss >> old_string >> new_string;
bool isReplaced = replaceString(ss, old_string, new_string);
if(isReplaced)
{
cout << ss << endl;
}
else
{
cout << "No match";
}
return 0;
}
bool replaceString(string& s, string& oldSubStr, string& newSubStr)
{
bool isreplaced = false;
int current_position = 0;
while(current_position<s.length())
{
int position = s.find(oldSubStr, current_position);
if(position==string::npos)
{
return isreplaced;
}
else
{
s.replace(position, oldSubStr.length(), newSubStr); // 从current_position开始,替换的子串长度,新的子串
current_position = position + newSubStr.length(); // 更新current_position
isreplaced = true;
}
}
return isreplaced;
}

对象作为函数的参数:
值传递引用传递都是允许的:
对象参数采用值传递,实际上是将对象的内容复制给函数参数

以引用传递的方式:函数的参数实际上是需要传递的对象的一个别名

推荐使用引用传递,因为值传递需要额外的时间和空间

创建对象的回数组:
Circle circleArray[10];

circleArray是一个对象数组,会调用无参构造函数初始化

对象数组例子:

circle.h

// 关于类的定义
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle
{
private:
double radius;
public:
// 定义数据域
//double radius;
// 构建函数
Circle();
// 构建函数
Circle(double);
// 定义函数
double getArea();
// define accessor
double getRadius();
// define mutator
void setRadius(double);
} ;
#endif

circle.cpp

// 类的实现
#include "E:\back_up\code\c_plus_code\chapter10\external_file\circle.h"
Circle::Circle()
{
radius = 1.0;
}
Circle::Circle(double new_radius)
{
radius = new_radius;
}
double Circle::getArea()
{
return 3.14*radius*radius;
}
double Circle::getRadius()
{
return radius;
}
void Circle::setRadius(double new_radius)
{
radius = new_radius;
}

main.cpp

#include <iostream>
#include <iomanip>
#include "E:\back_up\code\c_plus_code\chapter10\external_file\circle.h"
#include "E:\back_up\code\c_plus_code\chapter10\external_file\loan.h"
using namespace std;
const int SIZE = 10;
double sumCircle(Circle [], int);
void printCircle(Circle [], int);
int main(int argc, char *argv[])
{
Circle circle_array[SIZE];
for(int i=0; i<SIZE; i++)
{
circle_array[i].setRadius(i+5);
}
printCircle(circle_array, SIZE);
return 0;
}
double sumCircle(Circle circleArray[], int size)
{
double sumArea = 0;
for(int i=0; i<size; i++)
{
sumArea += circleArray[i].getArea();
}
return sumArea;
}
void printCircle(Circle circleArray[], int size)
{
cout << setw(25) << left << "Radius" << setw(8) << "Area" << endl;
for(int i=0; i<size; i++)
{
cout << setw(25) << left << circleArray[i].getRadius() << setw(8) << circleArray[i].getArea() << endl;
}
cout << "-----------------------------------------";
cout << "The total area of circles is " << sumCircle(circleArray, size) << endl;
}

8.实例成员和静态成员

概念: 实例变量和静态变量的区别:

实例变量: 在类的不同对象中是相互独立,互不影响的, 如Circle类中的radius

静态变量(类变量):在类的不同对象中是共享的,如在circle中添加静态变量numberOfObjects表示实例化的对象的个数 // 初始化

实例函数:

静态函数:

修饰符static

区别: 在类中,实例函数,实例变量从属于对象,只有创建对象后,才能通过特定的对象进行访问。

静态函数和静态变量可以通过任意的类对象来访问,也可以直接通过类名访问

注意与匿名类的区别  cout << Circle().radius()     cout << Circle(5).radius()这是匿名类

cout << Circle::number_of_object 以及Circle::getObjectNumber()是通过类名直接调用

例子程序:  注意程序中静态变量和静态函数的使用

circle.h

// 关于类的定义
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle
{
private:
double radius;
static int number_of_obj; // 静态变量 类变量
public:
// 定义数据域
//double radius;
// 构建函数
Circle();
// 构建函数
Circle(double);
// 定义函数
double getArea();
// define accessor
double getRadius();
// define mutator
void setRadius(double);
// 静态函数
static int getObjectNumber();
} ;
#endif

circle.cpp

// 类的实现
#include "E:\back_up\code\c_plus_code\chapter10\external_file\circle.h"
int Circle::number_of_obj = 0; // 注意初始化的位置在这里 静态变量
Circle::Circle()
{
radius = 1.0;
number_of_obj++; // 实例化对象时 ++
}
Circle::Circle(double new_radius)
{
radius = new_radius;
number_of_obj++; // ++
}
double Circle::getArea()
{
return 3.14*radius*radius;
}
double Circle::getRadius()
{
return radius;
}
void Circle::setRadius(double new_radius)
{
radius = new_radius;
}
int Circle::getObjectNumber()
{
return number_of_obj;
}

main.cpp

#include <iostream>
#include <iomanip>
#include "E:\back_up\code\c_plus_code\chapter10\external_file\circle.h"
#include "E:\back_up\code\c_plus_code\chapter10\external_file\loan.h"
using namespace std;
int main(int argc, char *argv[])
{
cout << "Created object number is " << Circle::getObjectNumber() << endl;
Circle circle1;
cout << "circle1 radius is " << circle1.getRadius() << endl;
cout << "circle1 areais " << circle1.getArea() << endl;
Circle circle2(5);
cout << "circle2 radius is " << circle2.getRadius() << endl;
cout << "circle2 areais " << circle2.getArea() << endl;
cout << "Created object number is " << Circle::getObjectNumber() << endl;
cout << "Created object number is " << circle1.getObjectNumber() << endl;
cout << "Created object number is " << circle2.getObjectNumber() << endl;
circle1.setRadius(10);
cout << "circle1 radius is " << circle1.getRadius() << endl;
cout << "circle1 areais " << circle1.getArea() << endl;
cout << "Created object number is " << Circle::getObjectNumber() << endl;
return 0;
}

结果:

建议使用类名访问静态函数和静态变量

只读成员函数

在成员函数后面加关键字const,这样相当于告诉编译器该成员函数不会改变数据域

只有实例才能被定义为只读函数

一般访问器函数被定义只读函数

9.从对象的角度考虑

   BMI指数获取

   重点: 类的定义,实现(具体)

              定义实例变量,实例函数,静态变量,静态函数

              定义只读函数

              调用

  code:

  bmi.h文件:

#ifndef BMI_H
#define BMI_H
#include <string>
using namespace std;
class BMI
{
private:
string user_name;
int user_age;
double user_weight;
double user_height;
static int current_user_num; // 静态变量
public:
// constructor function
BMI();
BMI(string& new_name, int new_age, double new_weight, double new_height);
// define accessor 只读函数
string getName() const;
int getAge() const;
double getWeight() const;
double getHeight() const;
// define mutator
void setName(string& new_new_name);
void setAge(int new_new_age);
void setHeight(double new_new_height);
void setWeight(double new_new_weight);
// function general
double getBMI() const;
string getStatus() const;
static int getCurrentUserNum(); // 只有实例方法才能被定义为只读函数
};
#endif

  bmi.cpp文件

 

#include "C:\Users\28491\Desktop\code\hello\external_file\bmi.h"
#include <string>
using namespace std;
int BMI::current_user_num = 0;
BMI::BMI()
{
user_name = "None";
user_age = 0;
user_height = 0.0;
user_weight = 0.0;
current_user_num++;
}
BMI::BMI(string& new_name, int new_age, double new_weight, double new_height)
{
user_name = new_name;
user_age = new_age;
user_weight = new_weight;
user_height = new_height;
current_user_num++;
}
// define accessor
string BMI::getName() const
{
return user_name;
}
int BMI::getAge() const
{
return user_age;
}
double BMI::getWeight() const
{
return user_weight;
}
double BMI::getHeight() const
{
return user_height;
}
// define mutator
void BMI::setName(string& new_new_name)
{
user_name = new_new_name;
}
void BMI::setAge(int new_new_age)
{
user_age = new_new_age;
}
void BMI::setWeight(double new_new_weight)
{
user_weight = new_new_weight;
}
void BMI::setHeight(double new_new_height)
{
user_height = new_new_height;
}
double BMI::getBMI() const
{
const double KILOGRAM_PER_POUND = 0.45359237;
const double METERS_PER_INCH = 0.0254;
double bmi = user_weight * KILOGRAM_PER_POUND / ((user_height * METERS_PER_INCH) * (user_height * METERS_PER_INCH));
return bmi;
}
string BMI::getStatus() const
{
double bmi = getBMI();
if(bmi<18.5)
return "Under_weight";
else if(bmi<25)
return "Normal";
else if(bmi<30)
return "Overweight";
else
return "Obesity";
}
int BMI::getCurrentUserNum()
{
return current_user_num;
}

main.cpp

#include <iostream>
#include <ctime>
#include <cmath>
#include <string>
#include "C:\Users\28491\Desktop\code\hello\external_file\bmi.h"
using namespace std;
int main(int argc, char *argv[])
{
string myname("zhangjun");
string hisname("wangwang");
BMI bmi_1(myname, 23, 120, 170);
cout << bmi_1.getName() << " is " << bmi_1.getAge() << " years old "
<< " and height is " << bmi_1.getHeight() << " and weight is "
<< bmi_1.getWeight() << endl;
cout << bmi_1.getName() << " BMI is " << bmi_1.getBMI() << " and status is "
<< bmi_1.getStatus() << endl;
cout << "Current user number is " << BMI::getCurrentUserNum() << endl;
BMI bmi_2;
bmi_2.setName(hisname);
bmi_2.setAge(28);
bmi_2.setHeight(180);
bmi_2.setWeight(100);
cout << bmi_2.getName() << " is " << bmi_2.getAge() << " years old "
<< " and height is " << bmi_2.getHeight() << " and weight is "
<< bmi_2.getWeight() << endl;
cout << bmi_2.getName() << " BMI is " << bmi_2.getBMI() << " and status is "
<< bmi_2.getStatus() << endl;;
cout << "Current user number is " << BMI::getCurrentUserNum() << endl;
//cout << "Bmi_1 name is " << bmi_1.getName() << endl;
//cout << "Bmi_1 age is " << bmi_1.getAge() << endl;
//cout << "Bmi_1 weight is " << bmi_1.getWeight() << endl;
//cout << "Bmi_1 height is " << bmi_1.getHeight() << endl;
//cout << "Current user is " << BMI::getCurrentUserNum() << endl;
return 0;
}

对象的合成:一个对对象可以包含另一个对象

实例研究: stack of integers类

栈(stack): 是一个 “后进先出” 的数据结构

应用: 编译器用栈处理函数的调用,用一个栈保存被调用函数的参数和局部变量。当一个函数调用另一个函数时,新函数的参数和局部变量被压入栈中。当一个函数完成工作,返回调用者时,它占用的空间将从栈中释放掉。

 stackofintegers.h

#ifndef STACK_H
#define STACK_H
class StackOfIntegers
{
private:
int size; // 栈的大小
int element[100];
public:
StackOfIntegers(); // 无参数构造函数
bool isEmpty() const; // 只读函数
int peek(); // 返回栈的第一个值
void push(int val); //入栈
int pop(); // 出栈
int getSize() const; // 返回栈的大小
};
#endif

 stackofintegers..cpp

#include "C:\Users\28491\Desktop\code\hello\external_file\stackofintegers.h"
StackOfIntegers::StackOfIntegers()
{
size = 0;
}
bool StackOfIntegers::isEmpty() const
{
return size == 0;
}
int StackOfIntegers::peek()
{
return element[size-1];
}
void StackOfIntegers::push(int val) // pop and push 函数的实现
{
element[size++] = val;
}
int StackOfIntegers::pop() // 不是只读函数,对private做出了修改
{
return element[--size];
}
int StackOfIntegers::getSize() const
{
return size;
}

main.cpp

#include <iostream>
#include <ctime>
#include <cmath>
#include <string>
#include "C:\Users\28491\Desktop\code\hello\external_file\stackofintegers.h"
using namespace std;
int main(int argc, char *argv[])
{
StackOfIntegers stack;
for(int i=0; i<15; i++)
{
stack.push(i);
if(i==8)
{
cout << "The first element in stack is " << stack.peek() << endl;
}
}
cout << "Stack Size is " << stack.getSize() << endl;
cout << "Pop a number " << stack.pop() << endl;
return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @   Alpha205  阅读(140)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示