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

怎样在设计网站做图赚钱吗磁力最好用的搜索引擎

怎样在设计网站做图赚钱吗,磁力最好用的搜索引擎,添加书签网站代码,p2p网上贷款网站建设方案.docx目录 1.面向过程和面向对象初步认识 2. 类的引入 3. 类的定义 4. 类的访问限定符及封装 4.1 访问限定符 4.2 封装 5. 类的作用域 6. 类的实例化 7. 类对象模型 7.1 类对象的存储方式 7.2 结构体内存对齐规则 7.3 特殊情况:空类的大小 8. this 指针 8.…

目录

1.面向过程和面向对象初步认识

2. 类的引入

3. 类的定义

4. 类的访问限定符及封装

4.1 访问限定符

4.2 封装

5. 类的作用域

6. 类的实例化

7. 类对象模型

7.1 类对象的存储方式

7.2 结构体内存对齐规则

7.3 特殊情况:空类的大小

8. this 指针

8.1 this 指针的引出

8.2 this 指针的特性

9. C 语言和 C++ 实现 栈(Stack) 的对比

💬 :如果你在阅读过程中有任何疑问或想要进一步探讨的内容,欢迎在评论区畅所欲言!我们一起学习、共同成长~!

👍 :如果你觉得这篇文章还不错,不妨顺手点个赞、加入收藏,并分享给更多的朋友噢~!


1.面向过程和面向对象初步认识

  • 面向过程(C 语言):关注解决问题的过程,分析求解步骤,通过函数调用逐步解决问题。
  • 面向对象(C++):基于面向对象编程,关注对象,将事情拆分成不同对象,依靠对象间的交互完成任务。

2. 类的引入

  • C 语言结构体:只能定义变量。
  • C++ 结构体:不仅能定义变量,还能定义函数。

示例:

#include <iostream>  
#include <cstdlib>   // 用于使用 malloc、free 和 perror 函数
#include <cassert>   typedef int DataType;// 定义栈结构体
struct Stack 
{void Init(size_t capacity) {_array = (DataType*)malloc(sizeof(DataType) * capacity);if (nullptr == _array) {perror("malloc申请空间失败");return;}_capacity = capacity;_size = 0;}// 接受一个常量引用参数,避免不必要的拷贝void Push(const DataType& data) {if (_size == _capacity) {size_t newCapacity = _capacity * 2;DataType* newArray = (DataType*)realloc(_array, sizeof(DataType) * newCapacity);if (newArray == nullptr) {perror("realloc申请空间失败");return;}_array = newArray;_capacity = newCapacity;}// 将元素存入栈中_array[_size] = data;++_size;}DataType Top() {// 确保栈不为空assert(_size > 0);// 返回栈顶元素return _array[_size - 1];}void Destroy() {if (_array) {free(_array);_array = nullptr;_capacity = 0;_size = 0;}}// 栈数组指针,用于存储栈中的元素DataType* _array;// 栈最多能存储的元素数量size_t _capacity;// 栈当前实际存储的元素数量size_t _size;
};int main() 
{// 创建一个栈对象Stack s;// 初始化栈,指定初始容量为 10s.Init(10);s.Push(1);s.Push(2);s.Push(3);std::cout << s.Top() << std::endl;s.Destroy();return 0;
}

C++ 中,更常用 class 代替 struct 来定义类

思考:为什么是 ++_size; 而非 _size++; ?

性能方面:现代编译器中两者在性能上差异微乎其微,但理论上前置自增性能更优。后置自增需要额外内存空间保存原值,并且操作结束后还要进行一次赋值;前置自增直接对变量进行自增并返回结果,没有这些额外开销。

代码语义方面:前置自增更直观地表达“先进行自增,再更新栈元素数量”的操作顺序。


3. 类的定义

  • 定义格式class 是定义类的关键字,ClassName 是类名,类定义结束后分号不能省略。
class className 
{// 类体:由成员函数和成员变量组成};  // 一定不要忘记分号int main()
{classname 对象名;对象名.成员函数名();
}

  • 类的成员:类中的变量称为类的属性或成员变量,类中的函数称为类的方法或成员函数。
  • 两种定义方式
    • (1)声明和定义全放类体中:成员函数在类中定义,编译器可能将其当作内联函数处理。
    • (2)类声明放 .h 文件,成员函数定义放 .cpp 文件:成员函数名前需加类名 :: 。一般推荐这种方式。
  • 成员变量命名规则建议:为避免成员变量和函数形参混淆,建议给成员变量加前缀或后缀,如 _year 或 mYear

4. 类的访问限定符及封装

4.1 访问限定符

访问限定符类外访问性作用域默认访问权限
public(公有)可直接访问从出现位置开始,到下一个访问限定符出现为止;若无下一个访问限定符,则到类结束struct 定义的类默认访问权限是 public
protected(保护)不能直接访问从出现位置开始,到下一个访问限定符出现为止;若无下一个访问限定符,则到类结束
private(私有)不能直接访问从出现位置开始,到下一个访问限定符出现为止;若无下一个访问限定符,则到类结束class 定义的类默认访问权限是 private

注意:访问限定符主要是在编译阶段发挥作用,用于保证代码的安全性和规范性,而在内存中,对象的成员变量并没有访问限定符的区分。

【面试题】C++ 中 struct 和 class 的区别?

C++需要兼容C语言,所以C++ 中 struct 可当作结构体使用。C++ 中 struct 也可定义类,与 class 定义类类似,区别在于 struct 定义的类默认访问权限是 publicclass 定义的类默认访问权限是 private。在继承和模板参数列表位置也有区别。

4.2 封装

  • 面向对象三大特性:封装、继承、多态。类和对象阶段主要研究封装特性。
  • 封装定义:将数据和操作数据的方法有机结合,隐藏对象属性和实现细节,仅对外公开接口与对象交互。
  • C++ 实现封装:通过类将数据和操作方法结合,利用访问权限隐藏内部实现细节,控制类外可直接使用的方法。

5. 类的作用域

 类定义了新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需用  ::  作用域操作符指明成员所属类域。

#include <iostream>
#include <string>
using namespace std;class Person 
{
public:// 声明成员函数void PrintPersonInfo();void SetName(const char* name);void SetGender(const char* gender);void SetAge(int age);
private:char _name[20];char _gender[3];int  _age;
};void Person::PrintPersonInfo() 
{cout << _name << " " << _gender << " " << _age << endl;
}void Person::SetName(const char* name) 
{// 将传入的姓名拷贝到成员变量_name中strncpy(_name, name, sizeof(_name) - 1);// 确保字符串以'\0'结尾_name[sizeof(_name) - 1] = '\0';
}void Person::SetGender(const char* gender) 
{strncpy(_gender, gender, sizeof(_gender) - 1);_gender[sizeof(_gender) - 1] = '\0';
}void Person::SetAge(int age) 
{_age = age;
}int main() 
{Person p;p.SetName("Alice");p.SetGender("女");p.SetAge(25);p.PrintPersonInfo();return 0;
}

6. 类的实例化

  • 定义:用类创建对象的过程称为类的实例化。
  • 特点
    • 类是对对象的描述,是模型,定义类时未分配实际内存空间。例如学生信息表可看成类,描述具体学生信息。
    • 一个类可实例化多个对象,实例化的对象占用实际物理空间,存储类成员变量。

7. 类对象模型

7.1 类对象的存储方式

在C++中,类对象的存储方式遵循以下规则:

类对象包含成员变量,但不包含成员函数。成员函数不属于某个具体的对象,而存放在公共的代码段,所有该类的对象共享同一份成员函数代码。

综上所述,类对象的大小本质上是其成员变量所占内存空间之和。但需要考虑内存对齐规则。

7.2 结构体内存对齐规则

  • 第一个成员的起始位置:第一个成员变量存放在与结构体偏移量为0的地址处。

  • 其他成员的对齐位置:其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数等于编译器默认的对齐数和该成员大小的较小值。在Visual Studio中,默认的对齐数为8。

  • 结构体的总大小:结构体总大小必须是最大对齐数(所有成员变量类型的最大者与默认对齐参数取最小)的整数倍。

  • 嵌套结构体的情况:如果嵌套了结构体,嵌套的结构体要对齐到自己的最大对齐数的整数倍处,结构体的整体大小是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍。

7.3 特殊情况:空类的大小

空类:没有任何成员变量和成员函数的类,或者只有成员函数而没有成员变量的类。

编译器会给空类分配1字节的空间,目的是为了让空类的对象能够拥有唯一的地址。


8. this 指针

8.1 this 指针的引出

C++ 中,当一个类有多个对象时,每个对象都有自己独立的成员变量。但是类的成员函数是所有对象共享的。

这就产生一个问题:当一个成员函数被调用时,如何知道是哪个对象在调用它呢?

#include <iostream>
using namespace std;class Date 
{
public:void Init(int year, int month, int day) {_year = year;_month = month;_day = day;}void Print() {std::cout << _year << "-" << _month << "-" << _day << std::endl;}private:int _year;int _month;int _day;
};int main() 
{Date d1, d2;d1.Init(2022, 1, 11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}

以上述代码为例,d1.Init(2022, 1, 11)d2.Init(2022, 1, 12)被调用时,Init函数将无法确定将这些值赋给d1的成员变量还是d2的成员变量。

为了解决以上问题,使用 this 指针。

C++中,每个非静态的成员函数都有一个隐藏的指针参数,这个指针就是 this 指针。它的主要作用是指向当前正在调用该成员函数的对象(不可为空)。

8.2 this 指针的特性

  • this指针的类型是 类类型 * const ,这意味着 this 指针是一个指向常量的指针,不能在成员函数中给this指针赋值。例如,对于一个Student类,this指针的类型就是 Student * const 

  • this 指针只能在类的成员函数内部使用,不能在类的外部单独使用。

  • this 指针是成员函数的第一个隐含的指针形参,不需在调用成员函数时显式传递。当对象调用成员函数时,编译器会自动将对象的地址作为实参传递给 this 指针。例如调用s1.display()时,编译器会自动将其转换为Student::display(&s1)。

  • this 指针不存储于对象本身中。在函数调用期间,this 指针的值保存在函数的栈帧中。函数执行完毕后,this 指针的值就会被销毁。


9. C 语言和 C++ 实现 栈(Stack) 的对比

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int DataType;typedef struct Stack 
{DataType* array;  // 用于存储栈中元素的数组指针int capacity;    int size;      // 栈中当前元素的数量   
} Stack;// 初始化栈
void StackInit(Stack* ps) 
{assert(ps); // 为栈的数组分配初始容量为3的空间ps->array = (DataType*)malloc(sizeof(DataType) * 3);if (NULL == ps->array) {assert(0); return;}ps->capacity = 3;  ps->size = 0;      
}void StackDestroy(Stack* ps) 
{assert(ps);  if (ps->array) {free(ps->array);  // 释放栈数组所占用的内存ps->array = NULL;ps->capacity = 0;ps->size = 0;}
}// 检查并扩容
void CheckCapacity(Stack* ps) 
{if (ps->size == ps->capacity) {int newcapacity = ps->capacity * 2;  DataType* temp = (DataType*)realloc(ps->array, newcapacity * sizeof(DataType));if (temp == NULL) {perror("realloc申请空间失败!!!");  return;}ps->array = temp;  ps->capacity = newcapacity;  }
}// 入栈
void StackPush(Stack* ps, DataType data) 
{assert(ps);  CheckCapacity(ps);  ps->array[ps->size] = data;  // 将元素存入栈数组ps->size++;  
}int StackEmpty(Stack* ps) 
{assert(ps);  return 0 == ps->size;  // 如果栈中元素数量为0,返回1表示空,否则返回0
}// 出栈
void StackPop(Stack* ps) 
{if (StackEmpty(ps))  return;ps->size--;  
}// 获取栈顶元素
DataType StackTop(Stack* ps) 
{assert(!StackEmpty(ps));  return ps->array[ps->size - 1];  
}// 获取栈中元素的数量
int StackSize(Stack* ps) 
{assert(ps);  return ps->size;  
}int main() 
{Stack s;StackInit(&s);  StackPush(&s, 1);  StackPush(&s, 2);  StackPush(&s, 3);  StackPush(&s, 4);  printf("%d\n", StackTop(&s));  printf("%d\n", StackSize(&s));  StackPop(&s);  StackPop(&s);  printf("%d\n", StackTop(&s));  printf("%d\n", StackSize(&s));  StackDestroy(&s);  return 0;
}

#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;typedef int DataType;class Stack 
{
public:// 初始化栈void Init() {_array = (DataType*)malloc(sizeof(DataType) * 3);if (NULL == _array) {perror("malloc申请空间失败!!!");  return;}_capacity = 3;  _size = 0;      }// 入栈void Push(DataType data) {CheckCapacity();  // 检查并扩容_array[_size] = data;  // 将元素存入栈数组_size++;  }// 出栈void Pop() {if (Empty())  return;_size--;  }// 获取栈顶元素DataType Top() { return _array[_size - 1]; }// 判断栈是否为空int Empty() { return 0 == _size; }// 获取栈中元素的数量int Size() { return _size; }void Destroy() {if (_array) {free(_array);  _array = NULL;_capacity = 0;_size = 0;}}
private:void CheckCapacity() {if (_size == _capacity) {int newcapacity = _capacity * 2;  DataType* temp = (DataType*)realloc(_array, newcapacity * sizeof(DataType));if (temp == NULL) {perror("realloc申请空间失败!!!");  return;}_array = temp;  _capacity = newcapacity;  }}
private:DataType* _array;  int _capacity;     int _size;        
};int main() 
{Stack s;s.Init();  s.Push(1);  s.Push(2);  s.Push(3);  s.Push(4);  cout << s.Top() << endl;  cout << s.Size() << endl;  s.Pop();  s.Pop();  cout << s.Top() << endl;  cout << s.Size() << endl;  s.Destroy(); return 0;
}
比较维度C 语言实现C++ 实现
数据与操作的组织方式结构体中只能定义存放数据的结构,数据和操作数据方式分离通过类将数据与操作数据方式完美结合
函数参数每个函数的第一个参数都是 Stack*不需显式传递 Stack * 参数,编译器自动维护
空指针检测函数中必须要对第一个参数(Stack*)检测是否为 NULL无需手动对类似指针参数进行空指针检测,编译器自动维护
调用方式调用时必须传递 Stack 结构体变量的地址使用时如同使用自身成员
访问控制通过访问权限(public、protected、private)控制哪些方法在类外可被调用,实现封装
实现复杂度涉及大量指针操作,容易出错,实现相对复杂代码结构更清晰,一定程度上降低了因指针操作不当导致的错误风险

http://www.dtcms.com/wzjs/89728.html

相关文章:

  • 邪恶漫画网站源码赣州seo排名
  • 太原整站优化百度数据平台
  • 云主机如何建网站网站收录大全
  • 哪个网站做平面能兼职企业网站有哪些功能
  • 老河口做网站浑江区关键词seo排名优化
  • 微信怎么制作自己的小程序厦门关键词优化平台
  • 强的网站建设公司网络营销是指什么
  • 如何给网站做提升网站收录情况
  • 农家院做宣传应该在哪个网站千锋教育培训机构学费
  • 互联网兼职做网站维护爱站网 关键词挖掘工具
  • 南昌网站建设方案维护seo咨询师招聘
  • 威客类网站开发广州网络推广定制
  • 上海网站建设信息网适合员工的培训课程
  • 湖州做网站公司汕头网站建设开发
  • 运动类网站东营网站建设
  • 网站建设徐州html网页制作成品
  • axure可以做网站外贸推广网站
  • 建设网站市场规模产品营销推广方案
  • 网站首页怎么做如何做好营销推广
  • 网站图片轮播怎么做的云南seo公司
  • 机械技术支持中山网站建设seo网站推广技术
  • 百度山西网站建设和百度推广网站推广的方法有哪几种
  • 幼儿园网站建设方案如何宣传推广
  • 福州做网站的公司有哪些夸克浏览器网页版入口
  • 做网站 注意宁波seo博客
  • 网站建设的功能有哪些安徽网络关键词优化
  • 武汉建设委员会安康地seo
  • 网站建设师杭州网站推广找哪家
  • 广东网站优化公司百度网盘手机版
  • 汕头网站排名优化以下属于网站seo的内容是