ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

C++程序设计学习笔记(三)

2026/9/20 16:00:53 拓冰建站 浏览量
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指针,它指向的是对象本身,值为当前被调用的成员函数所属对象的首地址。