第3章 Class and Object

news2024/11/27 8:41:42

构造函数

Guaranteed initialization with the constructor使用构造函数保证初始化

• If a class has a constructor, the compiler  automatically calls that constructor at the  point an object is created, before client  programmers can get their hands on the  object. 

• The name of the constructor is the same as  the name of the class.

构造函数:

1、没有返回类型

2、会被自动调用

Constructors with arguments有参构造函数

• The constructor can have arguments to allow  you to specify how an object is created, give it  initialization values, and so on.

Tree(int i) {…}
Tree t(12);

Constructor1.cpp

struct X{
  int i;
  X(int i);
  void prt();
};
X::X(int i){
  this -> i = i;
}
X::prt(){
  cout << i << endl;
}
int main(){
  X a; //无参构造,相当于a.X()
  X a(1);//有参构造,相当于a.X(1)
  X a=1; //变量初始化,相当于X a(1)
  int m(10);// 相当于 m = 1;
  a.prt();
}

想要i的值固定

struct X{
  int i = 100;
  X();
  void prt();
};
//X::X(){
//  i = 100;
//}
X::prt(){
  cout << i << endl;
}
int main(){
  X a; //无参构造,相当于a.X()
  a.prt();
}

//C++11会后才有这个特性:在成员变量定义的时候给初始值
//也可以采用构造函数的方式给成员变量赋初始值
X::X(){
  i = 100;
}

default意思:缺省;默认

缺省构造函数:没有参数的构造函数,可以是程序员定义的或者程序员没写时编译器提供的

普通构造函数:有参数的构造函数 X(int i);

如果没有无参构造函数,只有有参构造函数,则创建对象需要传入有参构造函数的参数

struct X{
  int i = 100;
  X(int i);
  void prt();
};
X::X(int i){
  this -> i = i;
}
X::prt(){
  cout << i << endl;
}
int main(){
  X a; //会报错
  X a(1);//需要传入参数
  a.prt();
}

如果没有定义有参构造函数,创建对象时就不能加参数

struct X{
  int i = 100;
  X();
  void prt();
};
X::X(){
  i = 100;
}
X::prt(){
  cout << i << endl;
}
int main(){
  X a; //正确
  X a(1);//会报错
  a.prt();
}
int main(){
  X b[10];//每个数组元素的i值为100
  //如果想给数组元素对象的成员变量赋值
  X b[10](7)//不对
  X b[10] ={1,2,3,4,5}//不对,因为只提供了5个值,数组元素一共有十个
}

The default constructor默认构造函数

• A default constructor is one that can be called with 

no arguments.

struct Y {
 float f; 
 int i; 
 Y(int a); 
};
Y y1[] = { Y(1), Y(2), Y(3) }; //OK,每个元素类型都是Y,没有给大小,根据大括号内动态决定
Y y2[2] = { Y(1) };//错误,大括号内只有一个,要有两个
Y y3[7];//不行,结构体内含有参构造函数,创建对象就必须传入参数
Y y4;//不行,因为结构体内含有参构造函数,创建对象就必须传入参数

“auto” default constructor

• If you have a constructor, the compiler ensures  that construction always happens.

• If (and only if) there are no constructors for a  class (struct or class), the compiler will  automatically create one for you.

The destructor析构函数

• In C++, cleanup is as important as initialization and is  therefore guaranteed with the destructor.

• The destructor is named after the name of the class 

with a leading tilde (~). The destructor never has any 

arguments.

struct Y { 
  public: 
 	 ~Y(); 
};
struct X{
  X(int i);
  void prt();
  ~X();
};
X::X(int i){
  this -> i = i;
}
X::prt(){
  cout << i << endl;
}
X::~X(){
  cout << "~X()" << i << endl;
}
int main(){
  X a(7); 
  X b(11);
  a.prt();
  b.prt();
}
/*
输出:
7
11
~X()11 // b的析构
~X()7 // a的析构
*/

先构造的后析构,因为可能后面的对象会用到前面的对象,所以先构造的不能先析构。

//代码复杂一些
int main(){
  X a(7); 
  {
  X b(11);
  }
  a.prt();
  //b.prt();
}
/*
输出:
~X()11 //b被析构,因为出了大括号这个生存期
7
~X()7 // a的析构
*/

说明析构发生在离开大括号的时候

Storage allocation

• The compiler allocates all the storage for a  scope at the opening brace of that scope. 

• The constructor call doesn’t happen until the sequence point where the object is defined.

Examlpe: Nojump.cpp

class X{
  private:
  	char* buf;
  public:
  	X(){buf = new char[1024];};
  	~X(){delete buf;}
}
X::X(){}
void f(int i){
  if(i < 10){
    goto jump1;
  }
  X x1;
  jump1;
  	switch(i){
      case 1:
        X x2;
        break;
      case 2:
        X x3;
        break;
    }
}
/*
如果i小于10,goto跳转到jump1,一旦进入到f函数,本地变量就被分配了空间,
但是此时x1的构造函数不会执行,程序结束时,由于析构函数找不到要delete的buf 
同理,switch的大括号规定了x2和x3的生命周期,一旦进入就给他们分配了空间,但由于case,x2或x3可能不会在对应的case下执行构造函数,最后析构的时候也会有问题。
解决方法:
1、不用goto
2、不用switch
*/

Aggregate initialization聚合体初始化

• int a[5] = { 1, 2, 3, 4, 5 }; 
• int b[6] = {5}; 
• int c[] = { 1, 2, 3, 4 }; 
– sizeof c / sizeof *c
• struct X { int i; float f; char c; }; 
– X x1 = { 1, 2.2, 'c' }; 
• X x2[3] = { {1, 1.1, 'a'}, {2, 2.2, 'b'} }; 
• struct Y { float f; int i; Y(int a); }; 
• Y y1[] = { Y(1), Y(2), Y(3) };

Defifinition of a class

• In C++, separated .h and .cpp files are used to define  one class.

• Class declaration and prototypes in that class are in  the header file (.h).

• All the bodies of these functions are in the source  file (.cpp).

compile unit

• The compiler sees only one .cpp file, and  generates .obj file。一个.cpp文件是一个编译单元,编译器在编译的时候只看见这一个.cpp文件

• The linker links all .obj into one executable  file

• To provide information about functions in  other .cpp files, use .h

The header fifiles

• If a function is declared in a header file, you  must include the header file everywhere the  function is used and where the function is  defined.

• If a class is declared in a header file, you must  include the header file everywhere the class is  used and where class member functions are  defined.

Header = interface

• The header is a contract (契约)between you and the 

user of your code. 

• The compile enforces the contract by  requiring you to declare all structures and  functions before they

Structure of C++ program

Declarations vs Defifinitions

• A .cpp file is a compile unit

• Only declarations are allowed to be in .h

• extern variables

• function prototypes

• class/struct declaration

#include

• #include is to insert the included file into  the .cpp file at where the #include statement  is.

• #include “xx.h”:first search in the current  directory, then the directories declared  somewhere

• #include <xx.h>:search in the specified  directories

• #include <xx>:same as #include <xx.h>

Standard header fifile structure

防止多次声明

#ifndef HEADER_FLAG 
#define HEADER_FLAG 
	// Type declaration here...
#endif // HEADER_FLAG

Tips for header

1. One class declaration per header file

2. Associated with one source file in the same 

prefix of file name.

3. The contents of a header file is surrounded  with #ifndef #define #endif

Clock display

Abstract

• Abstraction is the ability to ignore details of  parts to focus attention on a higher level of a  problem.

• Modularization is the process of dividing a  whole into well-defined parts, which can be  built and examined separately, and which  interact in well-defined ways.

Modularizing the clock display

NumberDisplay.h

#ifndef __NUMBER_DISPLAY__
#define __NUMBER_DISPLAY__

struct NumberDisplay{
  int value = 0;
  int limit = 0; //上界
  NumberDisPlay(int limit);
  int setValue(int value);
  int getValue();
  bool increase();
};

#endif

NumberDisplay.cpp

#include "NumberDisplay.h"

NumberDisplay::NumberDisPlay(int limit){
  this -> limit = limit;  
}

void NumberDisPlay::setValue(int value){
  this -> value = value;
}

int NumberDisPlay::getvalue(){
  return value;
}

bool NumberDisPlay::increase(){
  value++;
  if(value == limit){
    value = 0; //当值达到上限时,重新置零
    return true;
  }
  return false;
}

main.cpp

#include <iostream>
#include "NumberDisPlay"
using namespace std;

int main(){
  NumberDisPlay n(10);
  n.setValue(2);
  for(int i = 0; i < 15; i++){
    if(n.increase()){
      cout << "-------------" << endl;
    }
    cout << n.getValue() << endl;
  }
  return 0;
}
/*
输出:
3
4
5
6
7
8
9
------------------
0
1
2
3
4
5
6
7
*/

Clock.h

#ifndef __CLOCK_H__
#define __CLOCK_H__

#include "NumberDisPlay.h"

struct Clock{
  // NumberDisplay hour(24);编译会报错
  // NumberDisplay minute(60);
  //类内初始值只能放在花括号里,或放在等号右边,记住不能使用圆括号
  NumberDisplay hour=24;
  NumberDisplay minute=60;
  void dida();
  int getTime()
}

#endif

Clock.cpp

#include "Clock.h"

void Clock::dida(){
  if(minute.increase()){
    hour.increase();
  }  
}

int Clock::getTime(){
  return hour.getValue() *100 + minute.getValue(); 
}

main.cpp

#include <iostream>
#include "NumberDisPlay"
#include "Clock.h"

using namespace std;

int main(){
  // NumberDisPlay n(10);
  // n.setValue(2);
  // for(int i = 0; i < 15; i++){
  //   if(n.increase()){
  //     cout << "-------------" << endl;
  //   }
  //   cout << n.getValue() << endl;
  // }
  Clock clk;
  for(int i = 0; i < 123; i++){
    clk.dida();
    cout << clk.getTime() << endl;
  }
  return 0;
}

类内初始值只能放在花括号里,或放在等号右边,记住不能使用圆括号。

类外部创建对象时可以用圆括号,表示使用有参构造函数。

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

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

相关文章

Solidity基础五

暂时的一事无成也代表将来万事皆有可能&#xff01; 目录 一、对Solidity文件的理解 二、Solidity的导sol文件&#xff08;库、合约&#xff09; 三、Solidity的继承 1.继承的分类 2.继承的可见性 3.父合约构造函数的传参 4.调用父合约成员 5.重写 四、Solidity的抽象…

Solidity基础八

别慌&#xff0c;月亮也在大海某处迷茫 目录 一、Solidity 编程风格 1. 代码布局 2. 代码中各部分的顺序 3. 命名约定 二、Solidity 智能合约编写过程 1. solidity Hello World 2. 版本声明 3. 导入声明 4. 合约声明 三、Solidity 合约结构 智能合约 Test 四、So…

Solidity基础六

生活本来就是平凡琐碎的&#xff0c;哪有那么多惊天动地的大事&#xff0c;快乐的秘诀就是不管对大事小事都要保持热情 目录 一、Solidity的特殊变量(全局) 二、Solidity的不可变量 immutable的赋值方式 三、Solidity的事件与日志 事件和日志加深理解 四、Solidity的异常…

EMLP2021 | Google大模型微调经典论文prompt tuning

一、概述 title&#xff1a;The Power of Scale for Parameter-Efficient Prompt Tuning 论文地址&#xff1a;https://arxiv.org/abs/2104.08691 代码&#xff1a;GitHub - google-research/prompt-tuning: Original Implementation of Prompt Tuning from Lester, et al, …

系列一、RuoYi前后端分离(登录密码加密)

一、部署前后端服务 http://doc.ruoyi.vip/ruoyi-vue/ 二、现象 若依前后端环境分离版本&#xff0c;本地部署好前后端环境后&#xff0c;访问登录接口密码是明文的&#xff0c;这样显然hi不安全的&#xff0c;如下图所示&#xff1a; 三、解决方法 3.1、加密流程 ①、后端…

Linux-0.11 文件系统namei.c详解

Linux-0.11 文件系统namei.c详解 模块简介 namei.c是整个linux-0.11版本的内核中最长的函数&#xff0c;总长度为700行。其核心是namei函数&#xff0c;即根据文件路径寻找对应的i节点。 除此以外&#xff0c;该模块还包含一些创建目录&#xff0c;删除目录&#xff0c;创建目…

Day2:Windows网络编程-TCP

今天开始进入Windows网络编程的学习&#xff0c;在学习的时候总是陷入Windows复杂的参数&#xff0c;纠结于这些。从老师的讲解中&#xff0c;这些内容属于是定式&#xff0c;主要学习写的逻辑。给自己提个醒&#xff0c;要把精力放在正确的位置&#xff0c;不要无端耗费精力。…

【JavaScript】文件分片上传

文章目录 普通文件上传分片上传整体流程技术点分析文件选择方式隐藏input框&#xff0c;自定义trigger拖拽上传 分片动态分片 计算哈希workerrequestIdleCallback抽样 请求并发控制进度展示手动中止/暂停 合并流式并发合并 反思分片命名问题并发控制代码实现的问题 参考文献 普…

ChatGPT桌面客户端支持gpt4模型,附使用说明

#软件核心功能&#xff1a; 1、支持OpenAI官方秘钥及API2D双秘钥使用&#xff1b;如果全局魔法&#xff0c;可以自己用官方秘钥&#xff1b;没魔法国内可直接使用API2D秘钥&#xff1b; 2、内置GPT4模型选项&#xff0c;如果你的官方秘钥支持可直接使用&#xff1b;你也可以注册…

【Labview如何显示数据库表格中的内容】

Labview如何显示数据库表格中的内容 前提操作思路框图 前提 已经成功将数据库与Labview相连接&#xff0c;若还没有链接可以查看&#xff1a;Labview与SQL Server互联 进行操作 操作 思路 首先创建一个表格控件&#xff0c;通过一个按钮启动程序&#xff0c;通过程序调用数…

SAP MM 根据采购订单反查采购申请

如何通过采购订单号查询到其前端的采购申请号。 首先从采购申请的相关报表着手&#xff0c;比如ME5A, 发现它是可以满足需求的。 例如&#xff1a;如下的采购订单&#xff0c; 该订单是由采购申请10003364转过来的。 如果想通过这个采购订单找到对应的采购申请&#xff0c;在…

Packet Tracer – 配置命名标准 IPv4 ACL

Packet Tracer – 配置命名标准 IPv4 ACL 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 R1 F0/0 192.168.10.1 255.255.255.0 N/A F0/1 192.168.20.1 255.255.255.0 N/A E0/0/0 192.168.100.1 255.255.255.0 N/A E0/0/1 192.168.200.1 255.255.2…

第五十五天学习记录:C语言进阶:动态内存管理Ⅲ

柔性数组 C99中&#xff0c;结构中的最后一个元素允许是未知大小的数组&#xff0c;这就叫做柔性数组成员。 柔性数组的特点&#xff1a; 。结构体中的柔性数组成员前面必须至少有一个其他成员。 。sizeof返回的这种结构大小不包括柔性数组的内存。 。包含柔性数组成员的结构…

【C++学习】智能指针

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《C学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 智能指针 &#x1f96e;智能指针&#x1f362;为什么需要智能指针&#x1f362;RAII &#x1f96e;au…

chatgpt赋能python:Python自动开机:提高效率的必备工具

Python 自动开机&#xff1a;提高效率的必备工具 随着科技的发展&#xff0c;计算机在我们的日常生活中扮演了越来越重要的角色。为了提高工作效率和使用体验&#xff0c;越来越多的人开始探索利用自动化工具来简化日常操作。 Python 称得上是自动化领域中的一把利器。通过代…

SAP-MM费用类采购通过物料组确定科目

一、WRX的配置&#xff0c;分两类GR/IR科目&#xff1a; 1、做库存管理物料的GR/IR科目&#xff0c;需要配置评估类&#xff0c;此评估类就是物料主数据里配置的评估类&#xff1b; 2、非库存管理费用化物料的GR/IR科目&#xff0c;如固定资产、办公用品、低值易耗品等等&#…

chatgpt赋能python:Python生成C代码:如何用Python快速高效地生成C代码

Python生成C代码&#xff1a;如何用Python快速高效地生成C代码 在现代编程中&#xff0c;有许多原因需要编写C代码。C是一种高性能语言&#xff0c;它允许程序员直接操作计算机的硬件。但是&#xff0c;编写C代码需要花费大量的时间和精力。幸运的是&#xff0c;Python可以帮助…

Spring Boot问题汇总

1.IDEA里yaml文件编辑时没有提示 网上很多教程说在设置里的File Types里把yaml格式加入到关联中 但其实我打开IDEA默认就是这么设置的&#xff0c;所以并没有什么用处。 不过在翻看这篇教程&#xff08;IDEA创建yml文件不显示小树叶创建失败问题的解决方法-eolink官网&#x…

网络安全学习心得分享~

我的学习心得&#xff0c;我认为能不能自学成功的要素有两点。 第一点就是自身的问题&#xff0c;虽然想要转行学习安全的人很多&#xff0c;但是非常强烈的想要转行学好的人是小部分。而大部分人只是抱着试试的心态来学习安全&#xff0c;这是完全不可能的。 所以能不能学成并…

【Python】字符串操作

知识目录 一、写在前面✨二、字符串逆序三、打印菱形四、总结撒花&#x1f60a; 一、写在前面✨ 大家好&#xff01;我是初心&#xff0c;很高兴再次跟大家见面。&#xff08;相遇就是缘分啊&#xff09; 今天跟大家分享的文章是 Python中的字符串操作 &#xff0c;希望能帮助…