【CPP】类和对象

news/2024/11/17 21:52:40/

1- Classes and Objects

Structures

  • A struct in C is a type consisting of a sequence of data members
  • Some functions/Statements are needed to operate the data members of an object of a struct type

在这里插入图片描述

不不小心操作错误,不小心越界

Classes

  • You should be very careful to manipulated the data members in a struct object
  • Can we improve struct to a better one ?
  • Yes, it is class ! We can put some member functions in it
class Student
{private:static size_t student_total; // declaration only//inline static size_t student_total = 0; //C++17, definition outside isn't neededchar * name;int born;bool male; void setName(const char * s){strncpy(name, s, sizeof(name));}
};
Student yu;
yu.setName("Yu");

firstclass.cpp

#include <iostream>
#include <cstring>class Student
{public:char name[4];int born;bool male; void setName(const char * s){strncpy(name, s, sizeof(name));}void setBorn(int b){born = b;}void setGender(bool isMale){male = isMale;}void printInfo(){std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;}
};int main()
{Student yu;yu.setName("Yu");yu.setBorn(2000);yu.setGender(true);yu.born = 2001; // it can also be manipulated directlyyu.printInfo();std::cout << "It's name is " << yu.name << std::endl; return 0;
}
Name: Yu
Born in 2001
Gender: Male
It's name is Yu

Access Specifiers

  • You can protect data members by access specifier private
  • Then data member can only be accessed by well designed member functions

access_attribute.cpp

#include <iostream>
#include <cstring>class Student
{private:char name[4];int born;bool male; public:void setName(const char * s){strncpy(name, s, sizeof(name));}void setBorn(int b){born = b;}void setGender(bool isMale){male = isMale;}void printInfo(){std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;}
};int main()
{Student yu;yu.setName("Yu");yu.setBorn(2000);yu.setGender(true);yu.born = 2001; // you cannot access a private memberyu.printInfo();return 0;
}
access-attribute.cpp:37:8: error: 'born' is a private member of 'Student'yu.born = 2001; // you cannot access a private member^
access-attribute.cpp:8:9: note: declared private hereint born;^

Member Functions

  • A member function can be defined inside or outside class
  • 如果在类内部实现函数则就是inline 函数

function.cpp

#include <iostream>
#include <cstring>class Student
{private:char name[4];int born;bool male; public:void setName(const char * s){strncpy(name, s, sizeof(name));}void setBorn(int b){born = b;}// the declarations, the definitions are out of the classvoid setGender(bool isMale);void printInfo();
};void Student::setGender(bool isMale)
{male = isMale;
}
void Student::printInfo()
{std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}int main()
{Student yu;yu.setName("Yu");yu.setBorn(2000);yu.setGender(true);yu.printInfo();return 0;
}
Name: Yu
Born in 2000
Gender: Male

File Structures

  • The source code can be placed into multiple files

student.hpp

#pragma once#include <cstring>
class Student
{private:char name[4];int born;bool male; public:void setName(const char * s){strncpy(name, s, sizeof(name));}void setBorn(int b){born = b;}// the declarations, the definitions are out of the classvoid setGender(bool isMale);void printInfo();
};

student.cpp

#include <iostream>
#include "student.hpp"void Student::setGender(bool isMale)
{male = isMale;
}
void Student::printInfo()
{std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}

如果include <> 从编译器路径查找,如果是include "" 从编译器和当前目录找

main.cpp

#include "student.hpp"int main()
{Student yu;yu.setName("Yu");yu.setBorn(2000);yu.setGender(true);yu.printInfo();return 0;
}

CMakeList.txt

cmake_minimum_required(VERSION 3.12)project(persondemo)ADD_EXECUTABLE(persondemo main.cpp student.cpp)
cd multi-files
mkdir build
cd build
cmake ..
make
./persondemo
Name: Yu
Born in 2000
Gender: Male

2-Constructors and Destructors

Constructors

  • Different from struct in C, a constructor will be invoked when creating an object of a class

(1) struct in C: allocate memory
(2) class in C++: allocate memory & invoke a constructor

  • But, No constructor is defined explicitly in previous examples

(1) the compiler wil generate one with empty body

如果没有人为定义构造函数,则自动会有一个空的构造函数

  • The same name with the class
  • Have no return value

class Student
{private:char name[4];int born;bool male; public:Student(){name[0] = 0;born = 0;male = false;cout << "Constructor: Person()" << endl;}}Student(const char * initName, int initBorn, bool isMale){setName(initName);born = initBorn;male = isMale;cout << "Constructor: Person(const char, int , bool)" << endl;}
}
  • The members can also be initialized as follows
    Student(const char * initName): born(0), male(true){setName(initName);cout << "Constructor: Person(const char*)" << endl;}

把成员变量born 初始化为0 , 把male 初始化为true

constructor.cpp

#include <iostream>
#include <cstring>using namespace std;class Student
{private:char name[4];int born;bool male; public:Student(){name[0] = 0;born = 0;male = false;cout << "Constructor: Person()" << endl;}Student(const char * initName): born(0), male(true){setName(initName);cout << "Constructor: Person(const char*)" << endl;}Student(const char * initName, int initBorn, bool isMale){setName(initName);born = initBorn;male = isMale;cout << "Constructor: Person(const char, int , bool)" << endl;}void setName(const char * s){strncpy(name, s, sizeof(name));}void setBorn(int b){born = b;}// the declarations, the definitions are out of the classvoid setGender(bool isMale);void printInfo();
};void Student::setGender(bool isMale)
{male = isMale;
}
void Student::printInfo()
{std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}int main()
{Student yu;yu.printInfo();yu.setName("Yu");yu.setBorn(2000);yu.setGender(true);yu.printInfo();Student li("li");li.printInfo();Student xue = Student("XueQikun", 1962, true);//a question: what will happen since "XueQikun" has 4+ characters?xue.printInfo();Student * zhou =  new Student("Zhou", 1991, false);zhou->printInfo();delete zhou;return 0;
}
Constructor: Person()
Name: 
Born in 0
Gender: Female
Name: Yu
Born in 2000
Gender: Male
Constructor: Person(const char*)
Name: li
Born in 0
Gender: Male
Constructor: Person(const char, int , bool)
Name: XueQ�
Born in 1962
Gender: Male
Constructor: Person(const char, int , bool)
Name: Zhou�
Born in 1991
Gender: Female

Destructors

  • The destructor will be invoked when the object is destroyed
  • Be formed from the class name preceded by a tilde(~)
  • Have no return value, no parameters
    ~Student(){cout << "To destroy object: " << name << endl;delete [] name;}

析构函数只能有一个
析构函数常做的事情:释放内存,关闭文件,断掉网络etc

destructor.cpp

#include <iostream>
#include <cstring>using namespace std;class Student
{private:char * name;int born;bool male; public:Student(){name = new char[1024]{0};born = 0;male = false;cout << "Constructor: Person()" << endl;}Student(const char * initName, int initBorn, bool isMale){name =  new char[1024];setName(initName);born = initBorn;male = isMale;cout << "Constructor: Person(const char, int , bool)" << endl;}~Student(){cout << "To destroy object: " << name << endl;delete [] name;}void setName(const char * s){strncpy(name, s, 1024);}void setBorn(int b){born = b;}// the declarations, the definitions are out of the classvoid setGender(bool isMale);void printInfo();
};void Student::setGender(bool isMale)
{male = isMale;
}
void Student::printInfo()
{std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}int main()
{{Student yu;yu.printInfo();yu.setName("Yu");yu.setBorn(2000);yu.setGender(true);yu.printInfo();}Student xue = Student("XueQikun", 1962, true);xue.printInfo();Student * zhou =  new Student("Zhou", 1991, false);zhou->printInfo();delete zhou;return 0;
}
g++ destructor.cpp --std=c++11
Constructor: Person()
Name: 
Born in 0
Gender: Female
Name: Yu
Born in 2000
Gender: Male
To destroy object: Yu
Constructor: Person(const char, int , bool)
Name: XueQikun
Born in 1962
Gender: Male
Constructor: Person(const char, int , bool)
Name: Zhou
Born in 1991
Gender: Female
To destroy object: Zhou
To destroy object: XueQikun

人工手动调用析构函数 delete zhou,作用域结束跳出也会自动调用析构函数
如果对于new 的对象不进行手动删除delete 则作用域结束也不会动态调用析构函数,造成内存泄漏

    Student * class1 = new Student[3]{{"Tom", 2000, true},{"Bob", 2001, true},{"Amy", 2002, false},};
  • What is the different between the following two lines?
delete class1;
delete [] class1;

array.cpp

#include <iostream>
#include <cstring>using namespace std;class Student
{private:char * name;int born;bool male; public:Student(){name = new char[1024]{0};born = 0;male = false;cout << "Constructor: Person()" << endl;}Student(const char * initName, int initBorn, bool isMale){name =  new char[1024];setName(initName);born = initBorn;male = isMale;cout << "Constructor: Person(const char, int , bool)" << endl;}~Student(){cout << "To destroy object: " << name << endl;delete [] name;}void setName(const char * s){strncpy(name, s, 1024);}void setBorn(int b){born = b;}// the declarations, the definitions are out of the classvoid setGender(bool isMale);void printInfo();
};void Student::setGender(bool isMale)
{male = isMale;
}
void Student::printInfo()
{std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}int main()
{Student * class1 = new Student[3]{{"Tom", 2000, true},{"Bob", 2001, true},{"Amy", 2002, false},};class1[1].printInfo();delete class1;delete []class1;return 0;
}
Constructor: Person(const char, int , bool)
Constructor: Person(const char, int , bool)
Constructor: Person(const char, int , bool)
Name: Bob
Born in 2001
Gender: Male
To destroy object: Tom

数组调用析构函数delete class1 , 只会调用第一个对象的析构函数,后面的对象不会被调用

数组调用析构函数 delete [] class1,则会调用全部对象的析构函数

Constructor: Person(const char, int , bool)
Constructor: Person(const char, int , bool)
Constructor: Person(const char, int , bool)
Name: Bob
Born in 2001
Gender: Male
To destroy object: Amy
To destroy object: Bob
To destroy object: Tom

3-this pointer

Why is this needed

  • How does a member function know which name?

在这里插入图片描述

this Pointer

  • All methods in a function have a this pointer
  • It is set to the address of the object that invokes the method

在这里插入图片描述

this.cpp

#include <iostream>
#include <cstring>using namespace std;class Student
{private:char * name;int born;bool male; public:Student(){name = new char[1024]{0};born = 0;male = false;cout << "Constructor: Person()" << endl;}Student(const char * name, int born, bool male){this->name =  new char[1024];this->setName(name);this->born = born;this->male = male;cout << "Constructor: Person(const char, int , bool)" << endl;}~Student(){cout << "To destroy object: " << name << endl;delete [] name;}void setName(const char * name){strncpy(this->name, name, 1024);}void setBorn(int born){this->born = born;}// the declarations, the definitions are out of the classvoid setGender(bool isMale);void printInfo();
};void Student::setGender(bool isMale)
{male = isMale;
}
void Student::printInfo()
{std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}int main()
{Student * class1 = new Student[3]{{"Tom", 2000, true},{"Bob", 2001, true},{"Amy", 2002, false},};class1[1].printInfo();delete []class1;return 0;
}
Constructor: Person(const char, int , bool)
Constructor: Person(const char, int , bool)
Constructor: Person(const char, int , bool)
Name: Bob
Born in 2001
Gender: Male
To destroy object: Amy
To destroy object: Bob
To destroy object: Tom

4- const and static Members

const Variables

  • statements for constants

在这里插入图片描述

C++不推荐用 宏

const Members

  • const member variables behavior similar with normal const variables
  • const member functions promise not to modify member variables
class Student
{private:const int BMI = 24;public:Student(){BMI = 25;//can it be modified?int getBorn() const{born++; //Can it be modified?return born;}
};

常量函数,const 放在后面,不然跟前面的const int相冲突。不可以修改成员变量,born 是不可以被修改的,保证不修改函数里的变量

const.cpp

#include <iostream>
#include <cstring>using namespace std;class Student
{private:const int BMI = 24;char * name;int born;bool male; public:Student(){name = new char[1024]{0};born = 0;male = false;// BMI = 25;//can it be modified?cout << "Constructor: Person()" << endl;}Student(const char * name, int born, bool male){this->name =  new char[1024];setName(name);this->born = born;this->male = male;cout << "Constructor: Person(const char, int , bool)" << endl;}~Student(){cout << "To destroy object: " << name << endl;delete [] name;}void setName(const char * name){strncpy(this->name, name, 1024);}void setBorn(int born){this->born = born;}int getBorn() const{//born++; //Can it be modified?return born;}// the declarations, the definitions are out of the classvoid setGender(bool isMale);void printInfo();
};void Student::setGender(bool isMale)
{male = isMale;
}
void Student::printInfo()
{std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}int main()
{Student yu("Yu", 2000, true);cout << "yu.getBorn() = " << yu.getBorn() << endl;return 0;
}
Constructor: Person(const char, int , bool)
yu.getBorn() = 2000
To destroy object: Yu

static members

  • static members are not bound to class instances
class Student
{private:static size_t student_total; // declaration onlypublic:Student(){student_total++;}~Student(){student_total--;}static size_t getTotal() {return student_total;}
};// definition it here
size_t Student::student_total = 0; 

静态成员不绑定在类对象上,只有一个

static.cpp

#include <iostream>
#include <cstring>using namespace std;class Student
{private:static size_t student_total; // declaration only//inline static size_t student_total = 0; //C++17, definition outside isn't neededchar * name;int born;bool male; public:Student(){student_total++;name = new char[1024]{0};born = 0;male = false;cout << "Constructor: Person(): student_total = " << student_total << endl;}Student(const char * initName, int initBorn, bool isMale){student_total++;name =  new char[1024];setName(initName);born = initBorn;male = isMale;cout << "Constructor: Person(const char, int , bool): student_total = " << student_total << endl;}~Student(){student_total--;cout << "To destroy object: " << name ;cout << ". Then " << student_total << " students are left" << endl;delete [] name;}void setName(const char * s){strncpy(name, s, 1024);}void setBorn(int b){born = b;}static size_t getTotal() {return student_total;}// the declarations, the definitions are out sof the classvoid setGender(bool isMale);void printInfo();
};void Student::setGender(bool isMale)
{male = isMale;
}
void Student::printInfo()
{std::cout << "Name: " << name << std::endl;std::cout << "Born in " << born << std::endl;std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}size_t Student::student_total = 0; // definition it hereint main()
{cout << "---We have " << Student::getTotal() << " students---" << endl;Student * class1 = new Student[3]{{"Tom", 2000, true},{"Bob", 2001, true},{"Amy", 2002, false},};cout << "---We have " << Student::getTotal() << " students---" << endl;Student yu("Yu", 2000, true);cout << "---We have " << Student::getTotal() << " students---" << endl;class1[1].printInfo();delete []class1;cout << "---We have " << Student::getTotal() << " students---" << endl;return 0;
}
---We have 0 students---
Constructor: Person(const char, int , bool): student_total = 1
Constructor: Person(const char, int , bool): student_total = 2
Constructor: Person(const char, int , bool): student_total = 3
---We have 3 students---
Constructor: Person(const char, int , bool): student_total = 4
---We have 4 students---
Name: Bob
Born in 2001
Gender: Male
To destroy object: Amy. Then 3 students are left
To destroy object: Bob. Then 2 students are left
To destroy object: Tom. Then 1 students are left
---We have 1 students---
To destroy object: Yu. Then 0 students are left

静态函数里面不可以修改非静态数据


http://www.ppmy.cn/news/1188886.html

相关文章

huggingface离线模式及默认保存路径

T5Tokenizer.from_pretrained()函数会在线下载huggingface上的模型&#xff0c;并自动保存在C盘的.cache路径下&#xff1a; C:\Users\xxxxx\.cache\huggingface\hub\models--google--t5-v1_1-base # 这里xxxxx代表自己电脑用户名huggingface离线下载 以google/t5-v1_1-base为…

css矩形盒子实现虚线流动边框+css实现step连接箭头

由于项目里需要手写步骤条 且实现指定状态边框虚线流动效果&#xff0c;故使用css去绘制步骤条连接箭头和绘制边框流动效果 效果&#xff1a; 1.绘制步骤条连接箭头 <ul class"process-list"><div v-for"(process, index) in processes" :key&qu…

TypeScript -类 -类的基本定义

类的基本概念 类 就是对象的抽象&#xff0c;是对象的模板。 对象 就是类的一个具体实现。比如 【学生】是一个类&#xff0c;每个学生都有姓名、年龄两个属性&#xff0c;每个学生都有一个方法 sayHi()。【小明】是一个【学生】&#xff0c;也就是【学生】类的一个对象&#…

【C++ 系列文章 -- 程序员考试 下午场 C++ 专题 201711 】

文章目录 1.1 C 题目六1.1.1 填空&#xff08;1&#xff09;详解1.1.2 填空&#xff08;2&#xff09;详解1.1.2.1 C this 的使用 1.1.3 填空&#xff08;3&#xff09;详解1.1.4 填空&#xff08;4&#xff09;详解1.1.5 填空&#xff08;5&#xff09;详解1.1.6 填空&#xf…

精密数据工匠:探索 Netty ChannelHandler 的奥秘

通过上篇文章&#xff08;Netty入门 — Channel&#xff0c;把握 Netty 通信的命门&#xff09;&#xff0c;我们知道 Channel 是传输数据的通道&#xff0c;但是有了数据&#xff0c;也有数据通道&#xff0c;没有数据加工也是没有意义的&#xff0c;所以今天学习 Netty 的第四…

《微聊》JMeter性能测试报告

文章目录 准备工作JMeter准备工作本地配置代理 测试规划测试方向预期方向异常处理 压力测试录制注册功能压力注册功能压力脚本录制录制功能压力测试脚本完善注册功能压力测试结果 登录功能压力录制登录功能压力测试脚本构造压力测试数据完善登录功能性能测试脚本登录功能压力测…

apt-get-update报错

apt-get-update报错 错误一 E: Malformed entry 1 in list file /etc/apt/sources.list.d/pgdg.list (Component) E: The list of sources could not be read.查看原因&#xff1a; sudoedit /etc/apt/sources.list.d/pgdg.list可以看到显示的链接deb http://apt.postgresql…

【开题报告】基于SpringBoot的研究生管理系统的设计与开发

1.研究背景 研究生教育是高等教育体系中的重要组成部分&#xff0c;对于培养高层次、高水平的专业人才和推动科学研究具有重要意义。研究生管理是保证研究生培养质量和提升研究生培养工作效率的关键环节。然而&#xff0c;传统的研究生管理方式存在一些问题&#xff0c;如信息…