当前位置: 首页 > news >正文

做英文网站价格湖北百度推广公司

做英文网站价格,湖北百度推广公司,杭州建设工程交易平台,辽宁省建设工程信息网首页三、C对象模型和this指针 3.1 成员变量和成员函数分开存储 在C中&#xff0c;类内的成员变量和成员函数分开存储&#xff0c;只有非静态成员变量才属于类的对象上 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include <string.h> using namespace …

三、C++对象模型和this指针

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

在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上

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

3.2 this指针概念

通过上面我们知道在C++中成员变量和成员函数是分开存储的,每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码那么问题是:这—块代码是如何区分那个对象调用自己的呢?

C++通过提供特殊的对象指针, this指针,解决上述问题的。this指针指向被调用的成员函数所属的对象

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

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

this指针的用途:

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

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

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;class Person {
public:Person(int age) {//age = age;这样写无法区分,达到所需要求//this指针指向的是 被调用的成员函数所属的对象 即p1this->age = age;}Person& PersonAddAge(Person &p) {this->age += p.age;//this指向p2的指针,而*this指向的就是p2,返回本体用&//如果去掉&,就是返回值,答案为20,出来的是p2'一个新的对象return *this;}//解决名称冲突int age;};void test01() {Person p1(18);cout << "p1的年龄为:" << p1.age << endl;}

3.3 空指针访问成员函数

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

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

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;class Person {
public:void showClassName() {cout << "this is Person class" << endl;}void showPersonAge() {if (this == NULL) {return;}cout << "age = " << this->m_Age << endl;}int m_Age;};void test01() {Person* p = NULL;p->showClassName();//在新版VS里虽然能运行,但是仍存在问题,传入的指针为空p->showPersonAge();
}int main() {test01();system("pause");return 0;
}

3.4 const修饰成员函数

常函数:

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

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

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

常对象:

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

·常对象只能调用常函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;class Person {
public://常函数//this指针的本质 是指针常量 指针的指向是不可修改的//const Person * const this;//Person * const this 就是this在成员函数后面加const,修饰的是this指向,让指针指向的值也不可以修改void showPerson() const{//加上const则值也不可修改//this->m_A = 100; 报错//this = NULL; 已经指向 p,不可修改this->m_B = 100;}void func(){}int m_A;mutable int m_B;//特殊变量,即使在常函数中,也可以修改这个值
};void test01() {Person p;p.showPerson();
}//常对象
void test02() {const Person p;//在对象前加上const//p.m_A = 100;不可修改p.m_B = 100;//m_B是特殊的值,在常对象下也可修改//常对象只能调用常函数//p.func();不可调用普通的成员函数,因为普通的成员函数可以修改
}int main() {test01();test02();system("pause");return 0;
}

四、友元

生活中你的家有客厅(Public),有你的卧室(Private。客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去但是呢,你也可以允许你的好闺蜜好基友进去。

在程序里,有些私有属性也想让类外特殊的一些函数或者类进行访问,就需要用到友元.

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

友元的关键字为friend

友元的三种实现:

·全局函数做友元

·类做友元

·成员函数做友元

4.1 全局函数做友元

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;class Buliding {//这样就可以使其函数访问私有成员friend void goodGay(Buliding* bulidding);
public:Buliding() {m_SittingRoom = "客厅";m_BedRoom = "卧室";}public:string m_SittingRoom;//客厅
private:string m_BedRoom;//卧室};void goodGay(Buliding *bulidding) {cout << "好基友的全局函数 正在访问:" << bulidding->m_SittingRoom << endl;cout << "好基友的全局函数 正在访问:" << bulidding->m_BedRoom << endl;
}void test01() {Buliding bulidding;goodGay(&bulidding);}int main() {test01();system("pause");return 0;
}

4.2 类做友元

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;class Building;
class GoodGay {
public:GoodGay();void visit();Building * building;
};class Building {//这样GoodGay类的成员就可以访问本类的私有成员friend class GoodGay;
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 << "好基友的类正在访问:" << building->m_SittingRoom << endl;cout << "好基友的类正在访问:" << building->m_BedRoom << endl;}void test01() {GoodGay gg;gg.visit();
}int main() {test01();system("pause");return 0;
}

4.3 成员函数做友元

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;class Building;
class GoodGay {
public:GoodGay();void visit();//让visit函数可以访问Building中私有成员void visit2();//让visit2函数不可以访问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;
}

五、运算符重载

运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

5.1 加号运算符重载

作用:实现两个自定义数据类型相加的运算

eg.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;//加号运算符重载
class Person {public://1、成员函数重载 + 号成员函数重载本质调用//Person p3 = p1.operator+(p2);/*Person operator+(Person& p) {Person temp;temp.m_A = this->m_A + p.m_A;temp.m_B = this->m_B + p.m_B;return temp;}*/int m_A;int m_B;
};//2、全局函数重载 + 号
//全局函数重载本质调用
// Person p3 = operator+(p1, p2);
Person operator+(Person& p1, Person& p2) {Person temp;temp.m_A = p1.m_A + p2.m_A;temp.m_B = p1.m_B + p2.m_B;return temp;
}//函数重载的版本
Person operator+(Person& p1, int num) {Person temp;temp.m_A = p1.m_A + num;temp.m_B = p1.m_B + num;return temp;
}void test01() {Person p1;p1.m_A = 10;p1.m_B = 10;Person p2;p2.m_A = 10;p2.m_B = 10;Person p3;p3 = p1 + p2;//运算符重载`也可以发生函数重载Person p4 = p1 + 100;cout << "p3.m_A = " << p3.m_A << endl;cout << "p3.m_B = " << p3.m_B << endl;cout << "p4.m_A = " << p4.m_A << endl;cout << "p4.m_B = " << p4.m_B << endl;
}int main() {test01();system("pause");return 0;
}

注意:

1: 对于内置的数据类型的表达式的的运算符是不可能改变的

2: 不要滥用运算符重载

5.2 左移运算符<<重载(较难)

作用:可以输出自定义数据类型

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;//左移运算符重载
class Person {public://利用成员函数重载左移运算符//不会利用成员函数重载<<运算符,因为无法实现cout在左侧//void operator<<(Person &p) {//	//两个对象了//	//改为p.operator<<(cout) 简化版本 p << cout//}int m_A;int m_B;
};///只能利用全局函数重载左移运算符ostream& operator<<(ostream &cout,Person p)//本质operator<< ( cout ,p )简化 cout<< p 
{//全局只能有1个,所以用&coutcout << "m_A = " << p.m_A << " m_B = " << p.m_B;return cout;
}void test01() {Person p;p.m_A = 10;p.m_B = 10;cout << p << "hello,word" << endl;
}int main() {test01();system("pause");return 0;
}

5.3 递增运算符重载

作用:通过重载递增运算符,实现自己的整型数据

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;//重载递增运算符//自定义整型
class MyInteger {friend ostream& operator<<(ostream& cout, MyInteger myint);
public:MyInteger() {m_Num = 0;}//重载前置++运算符,返回引用为了一直对一个数据讲行递增操作MyInteger& operator++() {m_Num++;return *this;}//重载后置++运算符//void operator++(int) int代表占位参数,可以用于区分前置和后置MyInteger operator++(int) {//先记录当时结果MyInteger temp = *this;//后递增m_Num++;//最后将记录结果做返回return temp;}
private:int m_Num;};ostream& operator<<(ostream& cout, MyInteger myint) {cout << myint.m_Num;return cout;
}void test01() {MyInteger myint;cout << ++(++myint) << endl;
}
void test02() {MyInteger myint;cout << myint++ << endl;cout << myint << endl;
}int main() {test01();test02();system("pause");return 0;
}

5.4 赋值运算符重载

C++编译器至少给一个类添加4个函数

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

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

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

4.赋值运算符operator=,对属性进行值拷贝

如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;//重载赋值运算符
class Person {
public:Person(int age) {m_Age = new int(age);}~Person() {if (m_Age != NULL) {delete(m_Age);m_Age = NULL;}}Person& operator=(Person& p) {//应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝if (m_Age != NULL) {delete m_Age;m_Age = NULL;}this->m_Age = new int(*p.m_Age);return *this;}int* m_Age;};void test01() {Person p1(18);Person p2(20);Person p3(30);p3 = p2 = p1;//赋值操作,浅拷贝出现二次释放的问题,所以进行重载cout << "p1的年龄为:" << *p1.m_Age << endl;cout << "p2的年龄为:" << *p2.m_Age << endl;cout << "p3的年龄为:" << *p3.m_Age << endl;
}int main() {test01();system("pause");return 0;
}

5.5 关系运算符重载

作用:重载关系运算符,可以让两个自定义类型对象进行对比操作

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;//重载关系运算符class Person {
public:Person(string name,int age) {m_Name = name;m_Age = age;}//重载==号bool operator==(Person &p) {if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {return true;}return false;}bool operator!=(Person& p) {if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {return false;}return true;}string m_Name;int m_Age;
};void test01() {Person p1("Tom", 18);Person p2("Tom", 8);if (p1 == p2) {cout << "p1和p2是相等的!" << endl;}else {cout << "p1和p2是不相等的!" << endl;}if (p1 != p2) {cout << "p1和p2是不相等的!" << endl;}else {cout << "p1和p2是相等的!" << endl;}}int main() {test01();system("pause");return 0;
}

5.6 函数调用运算符()重载

·函数调用运算符()也可以重载

·由于重载后使用的方式非常像函数的调用,因此称为仿函数

·仿函数没有固定写法,非常灵活

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;//重载函数调用运算符
class MyPrint {
public://重载函数调用运算符void operator()(string test) {cout << test << endl;}
};void test02(string test) {cout << test << endl;}void test01() {MyPrint myPrint;myPrint("hello world!");//由于使用起来非常类似于函数调用,因此称为仿函数test02("hello world!");
}//仿函数没有固定写法,非常灵活
//加法类class MyAdd {
public:int operator()(int num1, int num2) {return num1 + num2;}};void test03() {MyAdd myAdd;int ret = myAdd(100, 100);cout << "ret = " << ret << endl;//匿名函数对象cout << MyAdd()(100, 100) << endl;
}int main() {test01();test03();system("pause");return 0;
}

http://www.tj-hxxt.cn/news/26725.html

相关文章:

  • 在线作图网站宁波网站推广找哪家
  • 移动网站开发每日新闻播报
  • 零代码网站开发工具产品推广营销方案
  • 网站建站建设多少钱小网站搜什么关键词好
  • 辽宁建设工程信息网官网新网站如何进入百度正版下载并安装
  • php做网站需要mysql么微信营销方法
  • 网站建设百家号2020做seo还有出路吗
  • 帮企业做网站的公司个人网页在线制作
  • 个人博客网站制作流程青海百度关键词seo
  • 玉树市公司网站建设什么是seo标题优化
  • 网站是空间备案云南网站seo服务
  • 惠州seo计费管理百度seo原理
  • 网站开发摊销年限网站alexa排名
  • 网站推荐男生正能量市场调研的四个步骤
  • 宜春做网站网站点击量 哪里查询
  • 公司产品网站谷歌海外推广
  • 弹窗网站制作器现在最好的免费的建站平台
  • 公司网站彩页怎么做软文免费发布平台
  • 2008iis搭建网站百度关键词排名怎么做
  • 做电销哪些网站可以找到客户端今天的新闻主要内容
  • 有哪些网站可以做简历热点新闻事件及评论
  • 丰台建站公司网络推广是什么专业
  • 武威网站建设优化网站视频
  • 自做淘宝客网站seo关键词优化推广
  • 免费独立网站建设交换友情链接前后必须要注意的几点
  • 网站怎么做长尾词seo运营是做什么的
  • 视频投票网站怎么做软文广告营销
  • 网站快速备案多少钱电子制作网站
  • 做系统下载网站建设百度快速收录技术
  • 网站开发合同范本渠道网官网