返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++的对象特性和友元是什么
  • 794
分享到

C++的对象特性和友元是什么

2023-06-29 02:06:36 794人浏览 八月长安
摘要

这篇文章主要介绍了c++的对象特性和友元是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++的对象特性和友元是什么文章都会有所收获,下面我们一起来看看吧。对象特征构造函数和析构函数对象的初始化和清理也是两

这篇文章主要介绍了c++的对象特性和友元是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++的对象特性和友元是什么文章都会有所收获,下面我们一起来看看吧。

    对象特征

    构造函数和析构函数

    对象的初始化和清理也是两个非常重要的安全问题

    一个对象或者变量没有初始状态,对其使用后果也是未知

    同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题 

    • 构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用

    • 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作

    构造函数语法:类名(){}

    构造函数,没有返回值也不写void

    函数名称与类名相同

    构造函数可以有参数,因此可以发生重载

    程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次 

    析构函数语法:~类名(){}

    析构函数,没有返回值也不写void

    函数名称与类名相同,在名称前加上符号~

    析构函数不可以有参数,因此不可以发生重载

    程序在调用对象前会自动调用析构,无须手动调用,而且只会调用一次 

    #include<iOStream>using namespace std;//对象的初始化和清理//1.构造函数  实现初始化的操作class Person {public://1构造函数//没有返回值  不用写void//函数名 与类名相同//构造函数可以有参数,可以发生重载//创建对象时,构造函数会自动调用,而且只调用一次Person() {cout<< "Person构造函数的调用" << endl;}//2.析构函数  实现清理的操作//没有返回值 不写void //函数名和类名相同 在名称前加一个~//析构函数不可以有参数,不可以发生重载//对象在销毁前 会自动调用析构函数 而且只会调用一次~Person() {cout << "Person析构函数的调用" << endl;}};//构造和析构都是必须有的实现,如果我们自己不提供,编译器会提供一个空实现的构造和析构void test01() {Person p;//在栈上的数据,test01执行完毕后,释放这个对象} int main() {test01();system("pause");return 0;}

    函数的分类以及调用

    构造函数的分类以及调用

    两种分类方式:

    • 按参数分为:有参构造和无参构造

    • 按类型分:普通构造和拷贝构造

    三种调用方式:

    • 括号法

    • 显示法

    • 隐式转换法

    #include<iostream>using namespace std;//构造函数的分类及调用//分类//按照参数分类  无参构造(默认构造)和有参构造//按照类型分类  普通构造 拷贝构造class Person {public://构造函数Person() { cout << "Person的无参构造函数调用" << endl;}Person(int a) {age = a;cout << "Person的有参构造函数调用" << endl;}//拷贝构造函数Person(const Person &p) {//将传入的人身上的所有属性,拷贝到“我”身上age = p.age;cout << "Person的拷贝构造函数调用" << endl;}~Person() {cout << "Person的析构函数调用" << endl;}int age;};//调用void test01() {//1.括号法//Person p1;//默认函数调用//Person p2(10);//有参构造函数//Person p3(p2);//拷贝构造函数//注意事项//调用默认构造函数的时候,不要加()//因为下面这行代码,编译器会认为是一个函数的声明,不会认为在创建对象//Person p1();  //2.显示法//Person p1;//Person p2 = Person(10);//有参构造//Person p3 = Person(p3);//拷贝构造//Person(10);//匿名对象 特点:当前行执行结束后,系统会立即回收掉匿名对象//// 注意事项2// 不要利用拷贝构造函数,初始化匿名对象  编译器会认为Person(p3) === Person p3;对象声明//Person(p3); //3.隐式转换法Person p4 = 10;//相当于 写了 Person p4 = Person(10); 有参构造Person p5 = p4;//拷贝构造}int main() {test01();system("pause");return 0;}

    拷贝构造函数调用时机

    拷贝构造函数调用时机通常有三种情况

    使用一个已经创建完毕的对象来初始化一个新对象

    值传递的方式给函数参数传值

    以值方式返回局部对象

    #include<iostream>using namespace std;//拷贝构造函数的调用时机//1.使用一个已经创建完毕的对象来初始化一个新对象//2.值传递的方式给函数参数传值//3.值方式返回局部对象class Person {public:Person() {cout << "Person的默认构造函数调用" << endl;}Person(int age) {cout << "Person的有参构造函数调用" << endl;m_Age = age;}Person(const Person &p) {cout << "Person的拷贝构造函数调用" << endl;m_Age = p.m_Age;}~Person() { cout << "Person析构函数调用" << endl;}int m_Age;};//拷贝构造函数的调用时机//1.使用一个已经创建完毕的对象来初始化一个新对象void test01() {Person p1(20);Person p2(p1);cout << "p2的年龄为:" << p2.m_Age << endl;}//2.值传递的方式给函数参数传值void doWork(Person p) {  } void test02() {Person p;doWork(p);} //3.值方式返回局部对象Person doWork2() {Person p1;return p1;}void test03() {Person p = doWork2();}int main() {//test01();//test02();test03();system("pause");return 0;}

     构造函数调用规则

    默认情况下,c++编译器至少给一个类添加3个函数

    默认构造函数(无参,函数体为空)

    默认析构函数(无参,函数体为空)

    默认拷贝构造函数,对属性进行值拷贝

    构造函数调用规则如下

    如果用户定义有参构造函数,c++不再提供默认无参构造,但是会提供默认拷贝构造

    如果用户定义拷贝构造函数,c++不再提供其他构造函数 

    #include<iostream>using namespace std;//构造函数的调用规则//1.创建了一个类,c++编译器会给每个类都添加至少三个函数//默认构造  (空实现)//析构函数  (空实现)//拷贝构造  (值拷贝)//2.如果我们写了有参构造函数,编译器就不再提供默认构造,依然提供拷贝构造//如果我们写了拷贝构造函数,编译器不再提供其他构造函数了class Person {public:Person(const Person& p) {cout << "Person的拷贝构造函数调用" << endl;m_Age = p.m_Age;} ~Person() {cout << "Person的析构函数调用" << endl;}int m_Age;};//void test01() {//Person p;//p.m_Age = 18;//Person p2(p);//cout << "p2的年龄为:" << p2.m_Age << endl;//}void test02() {Person p(28);Person p2(p);cout << "p2的年龄为:" << p2.m_Age << endl;}int main() {//test01();test02();system("pause");return 0;}

    深拷贝与浅拷贝

    • 浅拷贝:简单的赋值拷贝操作

    • 深拷贝:在堆区重新申请空间,进行拷贝操作

    #include<iostream>using namespace std;//深拷贝与浅拷贝class Person {public:Person() {cout << "Person的默认构造函数调用" << endl;}Person(int age,int height) {m_Age = age;m_Height = new int(height);cout << "Person的有参构造函数调用" << endl;}Person(const Person &p) {cout << "Person 拷贝构造函数的调用" << endl;m_Age = p.m_Age;//m_Height = p.m_Height; 编译器默认实现就是这行代码//深拷贝操作//如果不利于深拷贝在堆区创建内存,会导致浅拷贝带来的重复释放堆区问题m_Height = new int(*p.m_Height);}~Person() {//析构堆区,将堆区开辟数据做释放操作if (m_Height != NULL) {delete m_Height;m_Height = NULL;//浅拷贝带来的问题就是堆区的问题重复释放//浅拷贝的问题 要利用深拷贝进行解决}cout << "Person的析构函数调用" << endl;}int m_Age;//年龄int* m_Height;//身高};void test01() {Person p1(18,160);cout << "p1的年龄为:" << p1.m_Age <<"身高为:"<<*p1.m_Height << endl;Person p2(p1);cout << "p2的年龄为:" << p2.m_Age <<"身高为:"<<*p2.m_Height << endl;}int main() {test01();system("pause");return 0;}

    如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题 

    初始化列表

    作用:c++提供了初始化列表语法,用来初始化属性

    语法:构造函数():属性1(值1),属性2(值2)...{}

    #include<iostream>using namespace std;//初始化列表class Person {public://传统初始化操作//初始化列表初始化属性Person(int a,int b,int c) :m_A(a), m_B(b), m_C(c) { }int m_A;int m_B;int m_C;};void test01() {//Person p(10, 20, 30);Person p(30,20,10);cout << "m_A = " << p.m_A << endl;cout << "m_B = " << p.m_B << endl;cout << "m_C = " << p.m_C << endl;  }int main() {test01();system("pause");return 0;}

    类对象作为类变量

    c++类中的成员可以是另一个类的对象,我们称该成员为 对象成员

    例如:

    class A{}

    class B

    {

             A a;

    }

    B类中有对象A作为成员去,A为对象成员

    #include<iostream>using namespace std;//类对象作为类成员//手机类class Phone {public:Phone(string pName) {cout << "Phone的构造函数调用" << endl;m_PName = pName;}~Phone() {cout << "Phone的析构函数调用" << endl;}//手机品牌名称string m_PName; };//人类class Person {public://Phone m_Phone = pName  隐式转换法Person(string name, string pName):m_Name(name),m_Phone(pName){cout << "Person的构造函数调用" << endl;}~Person() {cout << "Person的析构函数调用" << endl;}//姓名string m_Name;//手机Phone m_Phone;};//当其他类对象作为本类成员,构造时先构造类对象,再构造自身,析构的顺序与构造相反void test01() {Person p("张三","苹果");cout << p.m_Name << "拿着" << p.m_Phone.m_PName << endl; }int main() {test01();system("pause");return 0;}

    静态成员

    静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

    静态成员分为:

    静态成员变量

    所有对象共享一份数据

    在编译阶段分配内存

    类内声明,类外初始化

    静态成员函数

    所有对象共享同一个函数

    静态成员函数只能访问静态成员变量 

    #include<iostream>using namespace std;//静态成员函数//所有对象共享同一个函数//静态成员函数只能访问静态成员变量class Person {public://静态成员函数static void func() {m_A = 100;//静态成员函数可以访问静态成员变量//m_B = 200;//静态成员函数不可以访问非静态成员变量,无法区分到底是哪个m_Bcout << "static void func的调用" << endl;}static int m_A;//静态成员变量int m_B;//非静态成员变量//静态成员函数也是有访问权限的private:static void func2() {cout << "static void func2的调用" << endl;}};int Person::m_A = 0;//有两种访问方式void test01() {//1.通过对象进行访问Person p;p.func();//2.通过类名访问Person::func();//Person::func2();类外访问不到私有的静态成员函数}int main() {test01();system("pause");return 0;}

    成员变量和成员函数分开储存

    在c++中,类的成员变量和成员函数分开存储

    只有非静态成员变量才属于类的对象上

    #include<iostream>using namespace std;//成员变量和成员函数是分开存储的class Person {int m_A;//非静态成员变量  属于类的对象上的static int m_B;//静态成员变量  不属于类的对象上void func() {}//非静态成员函数  不属于类的对象上static void func2() {}//静态成员函数  不属于类的对象上};int Person::m_B = 0;void test01() {Person p;//空对象占用的内存空间为:1//c++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置//每个空对象也应该有一个独一无二的内存地址cout << "size of p = "<<sizeof(p) << endl;}void test02() {Person p;cout << "size of p = " << sizeof(p) << endl;}int main() {//test01();test02();system("pause");return 0;}

    this指针的用途

    • this指针指向被调用的成员函数所属的对象

    • this指针是隐含每一个非静态成员函数内的一种指针

    • this指针不需要定义,直接使用即可

    this指针的用途:

    当形参和成员变量同名时,可用this指针来区分

    在类的非静态成员函数中返回对象本身,可使用return * this返回 

    #include<iostream>using namespace std;class Person {public:Person(int age) {//this指针指向被调用的成员函数所属的对象this->age = age;}int age;Person PersonAddAge(Person &p) {this->age += p.age;//this指向p2的指针,而*this指向的就是p2这个对象本体return *this;}}; //1.解决名称冲突void test01() {Person p1(18);cout << "p1的年龄为:" << p1.age << endl;}//2.返回对象本身用*thisvoid test02() {Person p1(10);Person p2(10);//链式编程思想p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);cout << "p2的年龄为:" << p2.age << endl;} int main() {//test01();test02();system("pause");return 0;}

    空指针访问成员

    c++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

    如果用到this指针,需要加以判断保证代码的健壮性

    #include<iostream>using namespace std;//空指针调用成员函数class Person {public: void showClassName() {cout << "this is Person class" << endl;}void showPersonAge() {//报错原因是因为传入的指针是为NULLif (this == NULL){return;}cout << "age = " <<this-> m_Age << endl;}int m_Age;};void test01() {Person* p = NULL;//p->showClassName();p->showPersonAge();}int main() {test01(); system("pause");return 0;}

    const修饰成员函数

    常函数

    成员函数后加const后我们称这个函数为常函数

    函数内不可以修改成员属性

    成员属性声明时加关键字mutable后,在常函数中依然可以修改

    常对象:

    声明对象前加const称该对象为常对象

    常对象只能调用常函数 

    #include<iostream>using namespace std;//空指针调用成员函数class Person {public: void showClassName() {cout << "this is Person class" << endl;}void showPersonAge() {//报错原因是因为传入的指针是为NULLif (this == NULL){return;}cout << "age = " <<this-> m_Age << endl;}int m_Age;};void test01() {Person* p = NULL;//p->showClassName();p->showPersonAge();}int main() {test01(); system("pause");return 0;}

    友元

    友元的目的就是让一个函数或者类访问另一个类中私有成员 

    友元关键字为friend  

    友元的三种实现:

    • 全局函数做友元

    • 类做友元

    • 成员函数做友元

    全局函数做友元

    #include<iostream>using namespace std;#include<string>//建筑物类class Building {//GoodGay全局函数是Building好朋友,可以访问Building中私有成员friend void goodGay(Building* building);public:Building() {m_SittingRoom = "客厅";m_BedRoom = "卧室";}public:string m_SittingRoom;//客厅private:string m_BedRoom;//卧室};//全局函数void goodGay(Building *building) {cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;cout << "好基友全局函数 正在访问:"<<building->m_BedRoom << endl;}void test01() {Building building;goodGay(&building);}int main() {test01();system("pause");return 0;}

    类做友元

    #include<iostream>using namespace std;#include<string>//类做友元class Building;class GoodGay {public:GoodGay();void visit();//参观函数 访问Building中的属性Building* building;};class Building {//GoodGay类是本来的好朋友,可以访问本类中私有成员friend class GoodGay;public:Building();public:string m_SittiingRoom;//客厅private:string m_BedRoom;//卧室};//类外写成员函数Building::Building() {m_SittiingRoom = "客厅";m_BedRoom = "卧室";}GoodGay::GoodGay() {//创建建筑物对象building = new Building;}void GoodGay::visit() {cout << "好基友类正在访问:"<<building->m_SittiingRoom << endl;cout << "好基友类正在访问:" << building->m_BedRoom << endl;}void test01() {GoodGay gg;gg.visit();}int main() {test01();system("pause");return 0;}

    成员函数做友元

    #include<iostream>using namespace std;#include<string>class Building;class GoodGay {public:GoodGay();void visit();//让visit函数可以访问Building中的私有成员void visit2();//让visit函数不可以访问Building中的私有成员Building* building;};class Building {//告诉编译器 GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员friend void GoodGay:: visit();public:Building();public:string m_SittingRoom;//客厅private:string m_BedRoom;//卧室 };//类外实现成员函数Building::Building() {m_SittingRoom = "客厅";m_BedRoom = "卧室";}GoodGay::GoodGay() {building = new Building;}void GoodGay::visit() {cout << "visit函数正在访问"<<building->m_SittingRoom << endl;cout << "visit函数正在访问" << building->m_BedRoom << endl;}void GoodGay::visit2() {cout << "visit2函数正在访问" << building->m_SittingRoom << endl;//cout << "visit2函数正在访问" << building->m_BedRoom << endl;}void test01() {GoodGay gg;gg.visit();gg.visit2();}int main() {test01(); system("pause");return 0;}

    关于“C++的对象特性和友元是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C++的对象特性和友元是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网其他教程频道。

    --结束END--

    本文标题: C++的对象特性和友元是什么

    本文链接: https://lsjlt.com/news/322083.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • C++的对象特性和友元是什么
      这篇文章主要介绍了C++的对象特性和友元是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++的对象特性和友元是什么文章都会有所收获,下面我们一起来看看吧。对象特征构造函数和析构函数对象的初始化和清理也是两...
      99+
      2023-06-29
    • C++的对象特性和友元你真的了解吗
      目录对象特征构造函数和析构函数函数的分类以及调用拷贝构造函数调用时机 构造函数调用规则深拷贝与浅拷贝初始化列表类对象作为类变量静态成员成员变量和成员函数分开储存this指针...
      99+
      2024-04-02
    • C++ 函数可以声明为友元函数吗?友元函数的特性是什么?
      是的,c++++ 函数可以声明为友元函数。友元函数具有以下特性:可以访问类的私有和受保护成员。不能直接访问类的 this 指针。可以定义在类的作用域之外。不是类的成员函数,不属于类的接口...
      99+
      2024-04-19
      c++ 友元函数 作用域
    • C++的友元和虚函数是什么
      这篇文章主要介绍了C++的友元和虚函数是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++的友元和虚函数是什么文章都会有所收获,下面我们一起来看看吧。友元可以是一个函数,该函数被称为友元函数;友元也可以是...
      99+
      2023-06-17
    • C++类和对象中友元函数怎么使用
      这篇文章主要介绍“C++类和对象中友元函数怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++类和对象中友元函数怎么使用”文章能帮助大家解决问题。友元用到关键字 friend浅解概念举一个非...
      99+
      2023-07-02
    • javascript的面向对象特性是什么
      这篇文章主要介绍“javascript的面向对象特性是什么”,在日常操作中,相信很多人在javascript的面向对象特性是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
      99+
      2024-04-02
    • Java克隆对象的特性是什么
      本篇内容介绍了“Java克隆对象的特性是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在java面向对象的编程当中,要复制引用类型的对象...
      99+
      2023-06-17
    • javascript对象属性的特征是什么
      本篇内容介绍了“javascript对象属性的特征是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!对象特征:1、writable:可写w...
      99+
      2023-06-25
    • C++中友元是什么意思
      这篇文章将为大家详细讲解有关C++中友元是什么意思,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一.友元函数友元函数可以是普通函数或者类成员函数。先看普通函数声明为友元函数:如下所示:#include&n...
      99+
      2023-06-29
    • Java中的面向对象特性是什么
      Java中的面向对象特性是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。对象与类:Date t=new Date(); 有2部分,new Date()构造了一个Date类型...
      99+
      2023-06-17
    • C++友元函数的作用是什么
      C++友元函数的作用是允许一个函数访问一个类的私有成员和保护成员。通常情况下,只有类的成员函数可以访问类的私有成员和保护成员,但是有...
      99+
      2023-10-11
      C++
    • C++中类的友元机制是什么
      这篇文章主要为大家详细介绍了C++中类的友元机制是什么,文中示例代码介绍的非常详细,具有一定的参考价值,发现的小伙伴们可以参考一下:类的友元  友元是C++提供的一种破坏数据封装和数据隐藏的机制。  通过将一个模块声明为另一个模块的友元,一...
      99+
      2023-06-06
    • Python面向对象的三大特性是什么
      这篇“Python面向对象的三大特性是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python面向对象的三大特性是什么...
      99+
      2023-07-02
    • C++ 友元函数详解:友元函数在面向对象设计中的应用?
      c++++ 友元函数是一种特殊函数,可访问另一个类的私有和受保护成员。通过声明友元函数,非成员函数可以与特定类交互。友元函数的应用包括操作符重载、i/o 操作和底层实现。例如,友元函数可...
      99+
      2024-04-29
      面向对象 友元函数 c++
    • Python面向对象三大特性是什么
      今天小编给大家分享一下Python面向对象三大特性是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。问:说说Python面...
      99+
      2023-06-19
    • C++简单又轻松的讲解类和对象中友元函数
      目录友元浅解概念友元目的友元的三种实现全局函数做友元类做友元成员函数做友元注意事项总结友元 用到关键字 friend 浅解概念 举一个非常实际的例子,假如端午节到了你煮了两种粽子,一...
      99+
      2024-04-02
    • C++中类和对象是什么
      这篇文章给大家分享的是有关C++中类和对象是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。类和对象<上>面向对象一直以来都是面向过程编程比如C语言,直到七十年代面向过程编程在开发大型程序时表现出不...
      99+
      2023-06-29
    • 友元函数对类的继承性有什么影响?
      友元函数的继承性当子类继承具有友元函数的类时:子类无法继承友元函数。父类的友元函数可以访问子类的私有成员。子类的友元函数无法访问父类的私有成员。 友元函数对类的继承性影响 前言 友元函...
      99+
      2024-04-17
      类继承 友元函数 access c++ 作用域
    • 友元函数对类的封装性有什么影响?
      友元函数对类的封装性有影响,包括降低封装性、增加攻击面和提高灵活性。它可以访问类的私有数据,如示例中定义为 person 类的友元的 printperson 函数可以访问 person ...
      99+
      2024-04-17
      友元函数 类的封装性 敏感数据 封装性
    • C++类和对象到底是什么
      目录1、C++ 中的类2、面向对象编程(Object Oriented Programming,OOP)1、C++ 中的类 C++ 中的类(Class)可以看做C语言中结构体(Str...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作