C++程序设计学习笔记(三)
目录
前言
1.构造函数
1.构造函数的作用
2.构造函数的定义
3.构造函数的使用
4.复制构造函数
5.类型转换构造函数
2.析构函数
3.类的静态成员
1.静态成员变量
2.静态成员函数
4.变量以及对象的生存期和作用域
5.成员对象和封闭类
1.封闭类构造函数的初始化列表
2.封闭类的复制构造函数
6.友元
1.友元的概念
2.友元函数
3.友元类
7.this指针
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
1.构造函数
1.构造函数的作用
构造函数的作用是完成对象的初始化工作,用来保证对象的初始状态是确定的。
2.构造函数的定义
构造函数定义格式如下:
类名(形参1,形参2,...形参n)
当类中没有定义构造函数的时候,系统会默认生成一个构造函数,这个构造函数参数个数为0、函数体也为空,这个构造函数被称为默认构造函数。
通常情况下,我们会声明一个和默认构造函数相同的函数给类的成员变量赋初值。
在下面的代码中,我们定义了一个学生类,类中定义了两个构造函数。
class Student {string name;int age;public:Student();Student(string,int);
};
Student::Student(){name = "柱子哥";age = 18;
}Student::Student(string studentName,int studentAge){name = studentName;age = studentAge;
}
第一个不带参数的构造函数是直接给成员变量赋了一个默认值,第二个构造函数是给类中的两个成员变量赋值。
3.构造函数的使用
当我们创建一个对象的时候,系统自动调用构造函数来初始化对象。对象生成之后,构造函数不再执行。传递参数的时候,系统调用有参构造函数。不传递参数的时候,调用无惨构造函数。
我们以下面的代码为例:
#include <iostream>
#include <string>
using namespace::std;class Student {
private:string name;int age;public:Student();Student(string,int);string getStudentName();int getStudentAge();void setStudentName(string);void setStudentAge(int);
};
void Student::setStudentName(string studentName){name = studentName;
}
void Student::setStudentAge(int studentAge){age = studentAge;
}
string Student::getStudentName(){return name;
}
int Student::getStudentAge(){return age;
}Student::Student(){name = "柱子哥";age = 18;
}
Student::Student(string studentName,int studentAge){name = studentName;age = studentAge;
}
int main(int argc, const char * argv[]) {Student student = Student();cout<<"学生姓名:"<<student.getStudentName()<<"\t学生年龄:"<<student.getStudentAge()<<endl;Student newStudent = Student("c++同学", 20);cout<<"学生姓名:"<<newStudent.getStudentName()<<"\t学生年龄:"<<newStudent.getStudentAge()<<endl;return 0;
}
当我们运行程序的时候,控制台打印信息如下:
学生姓名:柱子哥 学生年龄:18
学生姓名:c++同学 学生年龄:20
当我们调用无参构造函数的时候,学生姓名为柱子哥,年龄为18,这两个值是调用无参构造函数的时候,函数体内赋初值。当我们调用带参数的构造函数的时候,打印除了我们传递的name和age两个参数。
4.复制构造函数
5.类型转换构造函数
如果构造函数只有一个参数,则可以看做是类型转换构造函数,它的作用是进行类型的转换。以下面代码为例:
#include <iostream>
#include <string>
using namespace::std;class Demo {int value;
public:Demo(int i){value = i;cout<<"构造函数:value="<<value<<endl;}void printValue();
};
void Demo::printValue(){cout<<"value="<<value<<endl;
}
int main(int argc, const char * argv[]) {Demo demo = Demo(4);demo.printValue();demo = 6;demo.printValue();return 0;
}
我们在创建对象的时候,调用了有参数的构造函数,给Demo赋了一个初始值4,调用printValue函数的时候,打印出来的值为4;给这个对象赋值6的时候,系统做了一个类型转换,创建了一个临时的Demo对象,然后使用这个对象给demo赋值。
控制台打印结果如下:
构造函数:value=4
value=4
构造函数:value=6
value=6
2.析构函数
析构函数和构造函数一样,也是成员函数的一种,名字和类名相同,在类名的前面加上一个"~"符号。析构函数没有参数,也没有返回值。一个类中有且仅有一个析构函数,如果没有定义析构函数,系统也会生成一个默认的析构函数。析构函数的作用就是对象消亡的时候做一些善后工作,例如释放没有内存空间等。
还以上面定义的Demo类为例,我们定义一个析构函数,代码如下:
class Demo {int value;
public:Demo(int i){value = i;cout<<"构造函数:value="<<value<<endl;}~Demo(){cout<<"构造函数:value="<<value<<endl;}void printValue();
};
void Demo::printValue(){cout<<"value="<<value<<endl;
}
3.类的静态成员
定义类的成员时,前面加个static关键字后,该成员即成为静态成员。
类的静态成员被雷的所有对象共享,只有一份保存在内存中。
1.静态成员变量
类的静态变量成员在类中定义,类外面给变量赋值。格式如下:
类型 类名::静态成员变量 = 初值
类的静态变量有三种访问方式:
1.类名::静态成员变量名
2.对象名.静态成员变量名
3.对象指针->静态成员名
可以看下下面的简单的demo:
#include <iostream>
#include <string>
using namespace::std;class Demo {
public:static int staticValue;
};
int Demo::staticValue = 1;int main(int argc, const char * argv[]) {Demo demo = Demo();Demo *pointerDemo = new Demo;cout<<"Demo类的静态变量值:"<<Demo::staticValue<<endl;//第一种方式cout<<"Demo类的静态变量值:"<<demo.staticValue<<endl;//第二种方式cout<<"Demo类的静态变量值:"<<pointerDemo->staticValue<<endl;//第三种方式return 0;
}
2.静态成员函数
类的静态变量成员在类中定义,类外面给变量赋值。格式如下:
类型 类名::静态成员函数 = 函数实现
类的静态变量有三种访问方式:
1.类名::静态成员函数
2.对象名.静态成员函数
3.对象指针->静态成员函数
可以看下下面的简单的demo:
#include <iostream>
#include <string>
using namespace::std;class Demo {
public:static void printHello();
};
void Demo::printHello(){cout<<"Hello world!"<<endl;
}int main(int argc, const char * argv[]) {Demo demo = Demo();Demo *pointerDemo = new Demo;Demo::printHello();//第一种方式demo.printHello();//第二种方式pointerDemo->printHello();//第三种方式return 0;
}
4.变量以及对象的生存期和作用域
局部静态变量具有局部作用域,有全局的生命周期。
5.成员对象和封闭类
一个类的成员变量如果是另一个类的对象,给成员变量称为”成员变量“。这两个类为包含关系。包含成员对象的类叫做封闭类。
看下面的一段代码:
class ClassB {int cValue;int dValue;
public:void printClassBDescription();
};class ClassA {int aValue;int bValue;ClassB classB;
public:void printClassADescription();
};
在上面的代码中,ClassA类中定义了一个成员变量classB,classB的类型是类ClassB,那么ClassA和ClassB是包含关系。ClassA包含ClassB,ClassA是封闭类。
1.封闭类构造函数的初始化列表
当生成封闭类的对象进行初始化的时候,成员对象也需要初始化,调用成员对象的构造函数。定义封闭类的构造函数的时候,需要添加初始化列表,执行调用成员对象的哪个构造函数。在封闭类构造函数中添加初始化列表的格式如下:
封闭类名::构造函数(参数列表):成员变量1(参数列表),成员变量2(参数列表)...
实例代码如下:
class ClassB {int cValue;int dValue;
public:void printClassBDescription();
};class ClassA {int aValue;int bValue;ClassB classB;
public:void printClassADescription();ClassA(int,int,ClassB);ClassA(int valueA,int ValueB,int otherClassB):aValue(valueA),bValue(ValueB){}//构造函数
};ClassA::ClassA(int valueA,int valueB,ClassB otherClassB){aValue = valueA;bValue = valueB;classB = otherClassB;
}
封闭类对象生成的时候,先执行所有成员对象的构造函数,然后执行封闭类自己的构造函数。封闭类对象消亡的时候,先执行封闭类的析构函数,在执行成员变量的析构函数。
例如运行下面的代码:
#include <iostream>
#include <string>
using namespace::std;class ClassB {int cValue;int dValue;
public:void printClassBDescription();ClassB(int valueC,int valueD){cValue = valueC;dValue = valueD;cout<<"ClassB构造函数"<<endl;}~ClassB(){cout<<"ClassB析构函数"<<endl;}
};class ClassA {int aValue1;int aValue2;
public:ClassA();ClassA(int,int,ClassB);~ClassA(){cout<<"ClassA析构函数"<<endl;}
};
ClassA::ClassA(){aValue1 = 1;aValue2 = 2;cout<<"ClassA构造函数,aValue1="<<aValue1<<"\tbValue="<<aValue2<<endl;
}
ClassA::ClassA(int value1,int value2,ClassB classB):aValue1(value1),aValue2(value2){aValue1 = 1;aValue2 = 2;cout<<"ClassA构造函数,aValue1="<<aValue1<<"\tbValue="<<aValue2<<endl;
}int main(int argc, const char * argv[]) {ClassA(10, 20, ClassB(10, 10));return 0;
}
运行下面的代码之后,控制台打印信息如下:
ClassB构造函数
ClassA构造函数,aValue1=1 bValue=2
ClassA析构函数
ClassB析构函数
当我们创建封闭类之后,先调用成员对象ClassB的构造函数,然后调用封闭类ClassA的构造函数,程序运行结束之后,先运行封闭类的析构函数,然后运行成员对象的析构函数。
2.封闭类的复制构造函数
如果封闭类的对象是用默认复制函数初始化的,那么它包含的成员对象也会使用复制构造函数初始化。
6.友元
1.友元的概念
面向对象的程序设计要求在类外无法直接访问私有成员变量,必须通过共有的成员函数来访问。友元的出现解决了这个问题,通过友元机制我们可以访问类的私有成员变量。
友元使用关键字friend标识。friend出现在函数前面,该函数为类的友元函数。一个函数可以同时说明为多个类的友元函数,一个类中也可以有多个友元函数。friend在类前面,表示该类为友元类。
2.友元函数
友元函数的格式如下:
friend 返回值类型 函数名(参数);
实例代码如下:
#include <iostream>
#include <string>
using namespace::std;class Student {
private:string name;int age;
public:friend void show(Student &student1,Student &student2);//声明show函数为友元函数
};
//友元函数的实现
void show(Student &student1,Student &student2){cout<<"姓名:"<<student1.name<<endl;//可以访问Student的私有属性
}
3.友元类
友元类的定义格式如下:
friend class 类名
比如说我们有两个类NormalClassA和类FriendClass。
class NormalClassA {
private:int aValue;int bValue;
public:int cValue;
};class FriendClass {
private:string name;int age;
public:void show(NormalClassA &p){};};
在FriendClass中我们是无法直接访问NormalClass中的aValue和aValue的。但是我们声明NormalClass是FriendClass的友元类的时候,FriendClass的函数中就可以访问NormalClassA的私有属性。完整的代码如下:
#include <iostream>
#include <string>
using namespace::std;class NormalClassA {friend class FriendClass;
private:int aValue;int bValue;
public:int cValue;
};class FriendClass {
private:string name;int age;
public:void show(NormalClassA &p){cout<<"aValue:"<<p.aValue<<"\t年龄:"<<p.bValue<<endl;};};
7.this指针
this指针是C++实现封装的一种机制,类的每一个成员函数中都包含this指针,它指向的是对象本身,值为当前被调用的成员函数所属对象的首地址。