在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第十一篇博客。
本篇博客介绍了C++的构造函数和析构函数,也有几个类的实例。
本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。
目录
类的实例
这里有两个类的实例,巩固前面对类的理解。
立方体类
#include<iostream>
using namespace std;
class Cube {
private:
int a;
int b;
int c;
public:
int geta(void) {
return a;
}
void seta(int tempa) {
a = tempa;
}
int getb(void) {
return b;
}
void setb(int tempb) {
b = tempb;
}
int getc(void) {
return c;
}
void setc(int tempc) {
c = tempc;
}
int calculates(void) {
return 2 * a * b + 2 * a * c + 2 * b * c;
}
int calculatev(void) {
return a * b * c;
}
};
int main(void)
{
Cube cuboid;
cuboid.seta(10);
cuboid.setb(5);
cuboid.setc(15);
cout << "The total size is " << cuboid.calculates() << endl;
cout << "The volume is " << cuboid.calculatev() << endl;
return 0;
}
程序实现了一个Cube类,private权限的a,b,c分别代表长方体的长宽高,并提供了对应的get和set方法。类中还有calculates函数计算并返回长方体的表面积,calculatev函数计算并返回体积。
程序创建了一个此类的对象,并设置长宽高的值分别为10 5 15。最终计算并输出表面积和体积。
程序的输出是:
The total size is 550
The volume is 750
点和圆的关系
#include<iostream>
using namespace std;
class Point {
private:
double x;
double y;
public:
double getx(void) {
return x;
}
void setx(double tempx) {
x = tempx;
}
double gety(void){
return y;
}
void sety(double tempy) {
y = tempy;
}
};
class Circle {
private:
Point center;
double r;
public:
double getr(void) {
return r;
}
void setr(double tempr) {
r = tempr;
}
Point getcenter(void) {
return center;
}
void setcenter(Point tempcenter) {
center = tempcenter;
}
};
void judge(Circle c, Point p)
{
double x = p.getx() - c.getcenter().getx();
double y = p.gety() - c.getcenter().gety();
double distance = x * x + y * y;
if (distance > c.getr()* c.getr()) {
cout << "It is outside the circle" << endl;
}
else if (distance == c.getr()* c.getr()) {
cout << "It is on the circle" << endl;
}
else if (distance < c.getr()* c.getr()) {
cout << "It is in the circle" << endl;
}
}
int main(void)
{
Point center;
center.setx(8.0);
center.sety(6.0);
Circle c;
c.setr(10.0);
c.setcenter(center);
Point temp;
temp.setx(15);
temp.sety(16);
judge(c, temp);
return 0;
}
程序创建了Point类,有两个private权限的x和y变量,并提供了对应的get和set函数,表示点的坐标。还创建了Circle类,内有一个Point类的对象,和一个double类型的r,分别代表圆心和半径。并提供了对应的get和set函数。
程序的judge函数接收一个Circle类型的对象,和一个Point类型的对象,分别表示圆和点。随后获取点到圆心的距离的平方,与圆半径的平方比较,大于表示在圆外,小于表示在圆内,等于表示在圆上。随后输出判断结果。
程序的运行结果是:
It is outside the circle
分文件处理类
当程序内容比较多时,一般需要进行分文件处理。对类进行分文件处理时,通常将类的变量声明和成员函数声明放在头文件中,将成员函数的具体实现放在源文件中。
下面代码对上面圆和点的关系的例子进行改写。
#pragma once
#include<iostream>
using namespace std;
class Point {
private:
double x;
double y;
public:
double getx(void);
void setx(double tempx);
double gety(void);
void sety(double tempy);
};
Point.h提供了Point类的成员声明。
#include<iostream>
#include"Point.h"
using namespace std;
double Point::getx(void) {
return x;
}
void Point::setx(double tempx) {
x = tempx;
}
double Point::gety(void) {
return y;
}
void Point::sety(double tempy) {
y = tempy;
}
Point.cpp中具体实现了Point类中的函数,因此需要包含Point.h头文件。另外类名::函数名声明后面函数是这个类的成员函数,而不是独立的函数。
#pragma once
#include<iostream>
#include"Point.h"
using namespace std;
class Circle {
private:
Point center;
double r;
public:
double getr(void);
void setr(double temp);
Point getcenter(void);
void setcenter(Point tempcenter);
};
这是Circle.h头文件,因为这个类有Point类对象,因此需要包含Point.h。
#include<iostream>
#include"Circle.h"
using namespace std;
double Circle::getr(void) {
return r;
}
void Circle::setr(double tempr) {
r = tempr;
}
Point Circle::getcenter(void) {
return center;
}
void Circle::setcenter(Point tempcenter) {
center = tempcenter;
}
这是Circle.cpp,因为是Circle类的成员函数,因此需要包含Circle.h头文件。
#include<iostream>
#include"Point.h"
#include"Circle.h"
using namespace std;
void judge(Circle c, Point p);
int main(void)
{
Point center;
center.setx(8.0);
center.sety(6.0);
Circle c;
c.setr(10.0);
c.setcenter(center);
Point temp;
temp.setx(0);
temp.sety(0);
judge(c, temp);
return 0;
}
void judge(Circle c, Point p)
{
double x = p.getx() - c.getcenter().getx();
double y = p.gety() - c.getcenter().gety();
double distance = x * x + y * y;
if (distance > c.getr() * c.getr()) {
cout << "It is outside the circle" << endl;
}
else if (distance == c.getr() * c.getr()) {
cout << "It is on the circle" << endl;
}
else if (distance < c.getr() * c.getr()) {
cout << "It is in the circle" << endl;
}
}
这是对应的测试代码,因为涉及Circle和Point类,因此需要包含对应头文件。
程序的运行结果是:
It is on the circle
构造函数和析构函数简介
构造函数和析构函数
C++中,每个对象都有初始化设置和对象销毁前清理数据。
对象的初始化和清理是很重要的,一个对象或者变量没有初始化,则使用结果是未定义的。使用完一个对象或变量,没有及时清理,也会造成安全问题。
C++利用构造函数和析构函数解决这两个问题。这两个函数会被编译器自动调用,完成对象初始化和清理。如果我们不提供构造函数和析构函数,编译器会提供对应构造函数和析构函数的空实现。
构造函数主要作用是创建对象时为对象的成员属性赋值,由编译器自动调用。
析构函数主要作用是在对象销毁前由系统自动调用,执行一些清理工作。
构造函数的语法是:
类名(...){...}
构造函数无返回值,不写void,函数名就是类名。可以有参数,也可以无参数,可以发生重载。程序在创建对象时会自动调用,无需手动调用。
析构函数的语法是:
~类名(){...}
析构函数也没有返回值,不写void,函数名称与类名相同,但是要在名称前加~。析构函数不能有参数,不能发生重载。程序在对象销毁前自动调用析构函数,无需手动调用。
#include<iostream>
using namespace std;
class test {
public:
test() {
cout << "Begin" << endl;
}
~test() {
cout << "End" << endl;
}
};
int main(void)
{
test t;
return 0;
}
程序创建了test类,并提供了构造函数和析构函数。main函数中只创建了这个类的对象。
程序的输出是:
Begin
End
程序自动调用了构造和析构函数。
构造函数的调用
构造函数有普通构造和拷贝构造。
调用构造函数时可以用括号法,显示法和隐式转换法。
调用默认构造函数时不要加括号,因为这会被认为是函数声明。
匿名对象会在当前执行结束后立即回收,不要用拷贝函数初始化匿名对象。
#include<iostream>
using namespace std;
class test {
public:
int age;
test() {
cout << "This is A" << endl;
}
test(int num) {
age = num;
cout << "This is B" << endl;
cout << "Age = " << age << endl;
}
test(test& temp) {
age = temp.age;
cout << "This is C" << endl;
cout << "Age = " << age << endl;
}
};
int main(void)
{
test test1;
test test2(10);
test test3(test2);
return 0;
}
程序创建了一个test类,有成员变量age,提供了无参构造函数,接受一个int数值的构造函数,接受一个test类对象引用的构造函数。
程序使用了括号法调用构造函数,直接在名称后面的括号中放入参数。
程序的输出是:
This is A
This is B
Age = 10
This is C
Age = 10
#include<iostream>
using namespace std;
class test {
public:
int age;
test() {
cout << "This is A" << endl;
}
test(int num) {
age = num;
cout << "This is B" << endl;
cout << "Age = " << age << endl;
}
test(test& temp) {
age = temp.age;
cout << "This is C" << endl;
cout << "Age = " << age << endl;
}
};
int main(void)
{
test test1;
test test2 = 10;
test test3 = test2;
return 0;
}
这段代码使用了隐式转换法,在类名后面挂等号,等号后接参数。
程序的输出是:
This is A
This is B
Age = 10
This is C
Age = 10
#include<iostream>
using namespace std;
class test {
public:
int age;
test() {
cout << "This is A" << endl;
}
test(const int num) {
age = num;
cout << "This is B" << endl;
cout << "Age = " << age << endl;
}
test(const test& temp) {
age = temp.age;
cout << "This is C" << endl;
cout << "Age = " << age << endl;
}
};
int main(void)
{
test test1;
test test2 = test(10);
test test3 = test(test2);
return 0;
}
这段代码使用了显示法,在等号右侧用了括号法构造一个匿名对象。
程序的输出是:
This is A
This is B
Age = 10
This is C
Age = 10