私人彩票网站做几年牢,河北城乡建设厅网站显示不全,公司简介模板范文100字,学校网站建设调研报告本文阅读下述文章#xff0c;顺手记录学习《C面向对象程序设计》✍千处细节、万字总结#xff08;建议收藏#xff09;_c面向对象程序设计千处细节-CSDN博客 目录 前言 正文 浅拷贝和深拷贝 向函数传递对象 静态数据成员和静态成员函数 友元 友元函数 1、将非成员函数声明… 本文阅读下述文章顺手记录学习《C面向对象程序设计》✍千处细节、万字总结建议收藏_c面向对象程序设计千处细节-CSDN博客 目录 前言 正文 浅拷贝和深拷贝 向函数传递对象 静态数据成员和静态成员函数 友元 友元函数 1、将非成员函数声明为友元函数 2、将成员函数声明为友元函数 友元类 总结 前言
本文只对面向对象部分知识点有所提及 正文
浅拷贝和深拷贝
首先描述一下如何写拷贝函数 类名::类名(const 类名 对象名) { 拷贝构造函数的函数体 } 相关举例代码如下~~
class Score{
public:Score(int m, int f); //构造函数Score();Score(const Score p); //拷贝构造函数~Score(); //析构函数void setScore(int m, int f);void showScore();
private:int mid_exam;int fin_exam;
};Score::Score(int m, int f)
{mid_exam m;fin_exam f;
}Score::Score(const Score p)
{mid_exam p.mid_exam;fin_exam p.fin_exam;
}调用拷贝构造函数的一般形式为类名 对象2(对象1);类名 对象2 对象1;
Score sc1(98, 87);
Score sc2(sc1); //调用拷贝构造函数
Score sc3 sc2; //调用拷贝构造函数浅拷贝就是由默认的拷贝构造函数所实现的数据成员逐一赋值。通常默认的拷贝构造函数是能够胜任此工作的 但若类中含有指针类型的数据则这种按数据成员逐一赋值的方法会产生错误。
class Student{
public:Student(char *name1, float score1);~Student();
private:char *name;float score;
};如下语句会产生错误
Student stu1(白, 89);
Student stu2 stu1;上述错误是因为stu1和stu2所指的内存空间相同在析构函数释放stu1所指的内存后再释放stu2所指的内存会发生错误因为此内存空间已被释放。 主要问题是这样会导致stu1和stu2所指的内存空间一样需要给stu2重新生成新的空间 解决方法就是重定义拷贝构造函数为其变量重新生成内存空间。 Student::Student(const Student stu)
{name new char[strlen(stu.name) 1];if (name ! 0) {strcpy(name, stu.name);score stu.score;}
}向函数传递对象 1、使用对象作为函数参数对象可以作为参数传递给函数其方法与传递其他类型的数据相同。在向函数传递对象时是通过“传值调用”的方法传递给函数的。因此函数中对对象的任何修改均不影响调用该函数的对象实参本身。 2、使用对象指针作为函数参数对象指针可以作为函数的参数使用对象指针作为函数参数可以实现传值调用即在函数调用时使实参对象和形参对象指针变量指向同一内存地址在函数调用过程中形参对象指针所指的对象值的改变也同样影响着实参对象的值。 3、使用对象引用作为函数参数在实际中使用对象引用作为函数参数非常普遍大部分程序员喜欢使用对象引用替代对象指针作为函数参数。因为使用对象引用作为函数参数不但具有用对象指针做函数参数的优点而且用对象引用作函数参数将更简单、更直接。 这里重点是使用对象作为参数时候函数中对对象的任何修改都不影响对象本身 其次一般使用对象引用而非对象指针 下面选取文章的代码主要是要探讨代码运行结果~
#include iostream
using namespace std;class Point{
public:int x;int y;Point(int x1, int y1) : x(x1), y(y1) //成员初始化列表{ }int getDistance() {return x * x y * y;}
};void changePoint1(Point point) //使用对象作为函数参数
{point.x 1;point.y - 1;
}void changePoint2(Point *point) //使用对象指针作为函数参数
{point-x 1;point-y - 1;
}void changePoint3(Point point) //使用对象引用作为函数参数
{point.x 1;point.y - 1;
}int main()
{Point point[3] {Point(1, 1), Point(2, 2), Point(3, 3)};Point *p point;changePoint1(*p);cout the distance is p[0].getDistance() endl;p;changePoint2(p);cout the distance is p-getDistance() endl;changePoint3(point[2]);cout the distance is point[2].getDistance() endl;return 0;
}运行结果如下
the distance is 2
the distance is 10
the distance is 20 主要探讨第一个由于是传参并未对对象本身有影响所以仍然结果是112 静态数据成员和静态成员函数
在一个类中若将一个数据成员说明为static则这种成员被称为静态数据成员。与一般的数据成员不同无论建立多少个类的对象都只有一个静态数据成员的拷贝。从而实现了同一个类的不同对象之间的数据共享。 定义静态数据成员的格式如下static 数据类型 数据成员名; 几点特别的地方 1、静态数据成员的初始化与普通数据成员不同。静态数据成员初始化应在类外单独进行而且应在定义对象之前进行。一般在main()函数之前、类声明之后的特殊地带为它提供定义和初始化。 2、静态数据成员属于类所有这个类的对象都有的数据成员准确地说是属于类中对象的集合而不像普通数据成员那样属于某一对象因此可以使用“类名::”访问静态的数据成员。 格式如下类名::静态数据成员名。 3、静态数据成员与静态变量一样是在编译时创建并初始化。它在该类的任何对象被建立之前就存在。因此共有的静态数据成员可以在对象定义之前被访问。对象定以后共有的静态数据成员也可以通过对象进行访问。 其访问格式如下 对象名.静态数据成员名; 对象指针-静态数据成员名; 在类定义中前面有static说明的成员函数称为静态成员函数。静态成员函数属于整个类是该类所有对象共享的成员函数而不属于类中的某个对象。 静态成员函数的作用不是为了对象之间的沟通而是为了处理静态数据成员。 定义静态成员函数的格式如下 static 返回类型 静态成员函数名参数表 下面对静态成员函数的使用再做几点说明
1、一般情况下静态函数成员主要用来访问静态成员函数。当它与静态数据成员一起使用时达到了对同一个类中对象之间共享数据的目的。 2、私有静态成员函数不能被类外部的函数和对象访问。 3、使用静态成员函数的一个原因是可以用它在建立任何对象之前调用静态成员函数以处理静态数据成员这是普通成员函数不能实现的功能 4、编译系统将静态成员函数限定为内部连接也就是说与现行文件相连接的其他文件中的同名函数不会与该函数发生冲突维护了该函数使用的安全性这是使用静态成员函数的另一个原因。 5、静态成员函数是类的一部分而不是对象的一部分。如果要在类外调用公有的静态成员函数使用如下格式较好类名::静态成员函数名() 主要说明了静态成员函数主要是为了静态成员服务的为了能调用静态成员并实现一个类的多个对象直接可以实现静态成员数据共享由于静态成员函数属于类的一部分所以可以类外调用同时为了防止函数名冲突将其内部链接。 关于静态数据成员和静态成员函数的演示代码
#include iostream
using namespace std;class Score{
private:int mid_exam;int fin_exam;static int count; //静态数据成员用于统计学生人数static float sum; //静态数据成员用于统计期末累加成绩static float ave; //静态数据成员用于统计期末平均成绩
public:Score(int m, int f);~Score();static void show_count_sum_ave(); //静态成员函数
};Score::Score(int m, int f)
{mid_exam m;fin_exam f;count;sum fin_exam;ave sum / count;
}Score::~Score()
{}/*** 静态成员初始化 ***/
int Score::count 0;
float Score::sum 0.0;
float Score::ave 0.0;void Score::show_count_sum_ave()//静态成员函数
{cout 学生人数: count endl;cout 期末累加成绩: sum endl;cout 期末平均成绩: ave endl;
}int main()
{Score sco[3] {Score(90, 89), Score(78, 99), Score(89, 88)};sco[2].show_count_sum_ave(); //对象调用~Score::show_count_sum_ave(); //类外调用静态成员函数//结果都一样return 0;
}由于调用的是静态成员函数一个对象调用和一个类外调用最终结果都一样
学生人数: 3
期末累加成绩: 276
期末平均成绩: 92
学生人数: 3
期末累加成绩: 276
期末平均成绩: 92 友元
类的主要特点之一是数据隐藏和封装即类的私有成员或保护成员只能在类定义的范围内使用也就是说私有成员只能通过它的成员函数来访问。但是有时为了访问类的私有成员而需要在程序中多次调用成员函数这样会因为频繁调用带来较大的时间和空间开销从而降低程序的运行效率。为此C提供了友元来对私有或保护成员进行访问。这个是重点主要可以访问对私有或者保护成员 友元包括友元函数和友元类。
友元函数
友元函数既可以是不属于任何类的非成员函数也可以是另一个类的成员函数。 友元函数不是当前类的成员函数但它可以访问该类的所有成员包括私有成员、保护成员和公有成员。这一点就是上诉C提供友元的主要原因是为了能访问私有或保护成员。
在类中声明友元函数时需要在其函数名前加上关键字friend。此声明可以放在公有部分也可以放在保护部分和私有部分。友元函数可以定义在类内部也可以定义在类外部。
1、将非成员函数声明为友元函数
#include iostream
using namespace std;
class Score{
private:int mid_exam;int fin_exam;
public:Score(int m, int f);void showScore();friend int getScore(Score ob);
};Score::Score(int m, int f)
{mid_exam m;fin_exam f;
}int getScore(Score ob)
{return (int)(0.3 * ob.mid_exam 0.7 * ob.fin_exam);
}int main()
{Score score(98, 78);cout 成绩为: getScore(score) endl;return 0;
}这里我一开始想着不用友元也可以然后改了下代码发现主要问题 如果 getScore(Score ob)不是Score的友元函数那么getScore(Score ob)就不可以访问其中的私有成员mid_examfin_exam从而本身就会报错。 当然我们可以直接在类里写成员函数直接传出私有成员或者直接在类里直接写上这个函数就不会需要友元但仍然需要知道这里的友元主要是为了访问私有成员。但是当一个函数需要访问多个类时友元函数非常有用普通的成员函数只能访问其所属的类但是多个类的友元函数能够访问相关的所有类的数据。 同时因为友元函数不是类的成员所以它不能直接访问对象的数据成员也不能通过this指针访问对象的数据成员它必须通过作为入口参数传递进来的对象名或对象指针、对象引用来访问该对象的数据成员。
2、将成员函数声明为友元函数
一个类的成员函数可以作为另一个类的友元它是友元函数中的一种称为友元成员函数。友元成员函数不仅可以访问自己所在类对象中的私有成员和公有成员还可以访问friend声明语句所在类对象中的所有成员这样能使两个类相互合作、协调工作完成某一任务。
#include iostream
#include string
using namespace std;class Score; //对Score类的提前引用说明
class Student{
private:string name;int number;
public:Student(string na, int nu) {name na;number nu;}void show(Score sc);
};class Score{
private:int mid_exam;int fin_exam;
public:Score(int m, int f) {mid_exam m;fin_exam f;}friend void Student::show(Score sc);
};void Student::show(Score sc) {cout 姓名 name 学号 number endl;cout 期中成绩 sc.mid_exam 期末成绩 sc.fin_exam endl;
}int main() {Score sc(89, 99);Student st(白, 12467);st.show(sc);return 0;
}一个类的成员函数作为另一个类的友元函数时必须先定义这个类。并且在声明友元函数时需要加上成员函数所在类的类名就如同上面所说上述成员函数声明为友元成员函数也可以利用第一条的非成员函数替代只要在俩个类都声明友元函数即可并同时引用俩个类。
友元类
操作是直接friend一个类就行 当一个类被说明为另一个类的友元类时它所有的成员函数都成为另一个类的友元函数这就意味着作为友元类中的所有成员函数都可以访问另一个类中的所有成员。
友元关系不具有交换性和传递性。就不存在Y是X友元Z是Y友元能得出Z是X友元这种情况这是不对的。 总结
本文是阅读之后的摘要内容主要记录了拷贝传递对象静态与友元的一些内容。 在此继续感谢佬的付出 推荐学习博客 https://xxetb.xetslk.com/s/4GgGz6