c++学习第七天

devtools/2025/1/23 1:58:46/

创作过程中难免有不足,若您发现本文内容有误,恳请不吝赐教。


提示:以下是本篇文章正文内容,下面案例可供参考。

一、const成员函数

//Date.h#pragma once#include<iostream>
using namespace std;class Date
{
public:Date(int year = 1, int month = 1, int day = 1);//两个Print()可以同时存在,构成函数重载void Print() const;void Print();private:int _year;int _month;int _day;
};
//Date.cpp#include"Date.h"Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;// 检查日期是否合法if (month < 1 || month > 12|| day < 1 || day > GetMonthDay(year, month)){cout << "非法日期" << endl;// exit(-1);}
}//void Date::Print(const Date* this) 
void Date::Print() const
{cout << _year << "年" << _month << "月" << _day << "日" << endl;
}//void Date::Print(Date* this) 
void Date::Print()
{cout << _year << "年" << _month << "月"  << endl;
}
//Test.cpp#include"Date.h"int main()
{const Date d1(2025, 1, 1);d1.Print();Date d2(2025, 1, 2);d2.Print();
}


//Date.hbool operator<(const Date& d) const;bool operator==(const Date& d) const;bool operator<=(const Date& d) const;bool operator>(const Date& d) const;bool operator>=(const Date& d) const;bool operator!=(const Date& d) const;Date& operator+=(int day);Date operator+(int day) const;Date& operator-=(int day);Date operator-(int day) const;Date& operator++();Date operator++(int);Date& operator--();Date operator--(int);int operator-(const Date& d) const;

        简单来说:只读函数可以加const,内部不涉及修改成员的都是只读函数


二、取地址及const取地址操作符重载

//Test.cpp#include"Date.h"int main()
{const Date d1(2025, 1, 2);d1.Print();cout << &d1 << endl;Date d2(2025, 1, 7);d2.Print();cout << &d2 << endl;return 0;
}

        理论上上面的代码是不能运行的,因为自定义类型使用运算符需要重载。因为取地址及const取地址操作符重载这两个默认成员函数一般不用重新定义 ,编译器默认会生成。

//自己写如下:
//日常使用自动生成的就可以了Date* operator&()
{return this;
}const Date* operator&() const
{return this;
}
// 不想被取到有效地址才自己写
Date* operator&()
{return nullptr;
}const Date* operator&() const
{return this;
}


三、流插入和流提取

//Date.hvoid operator<<(ostream& out);
//Date.cppvoid Date::operator<<(ostream& out)
{out << _year << "/" << _month << "/" << _day << endl;
}
//Test.cpp#include"Date.h"int main()
{Date d1(2025, 1, 21);cout << d1 ;return 0;
}

原因:参数顺序不匹配

//Test.cpp#include"Date.h"int main()
{Date d1(2025, 1, 21);d1 << cout ;return 0;
}


 不能写成成员函数,因为成员函数this指针永远占据第一个,所以只能往全局上写。

//Date.h#pragma once#include<iostream>
using namespace std;class Date
{// 友元声明//因为operator<<写在函数外面不能访问到_year,_month,_dayfriend void operator<<(ostream& out, const Date& d);Date(int year = 1, int month = 1, int day = 1);public:void Print();private:int _year;int _month;int _day;
};void operator<<(ostream& out, const Date& d);
//Date.cpp#include"Date.h"Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;// 检查日期是否合法if (month < 1 || month > 12|| day < 1 || day > GetMonthDay(year, month)){cout << "非法日期" << endl;// exit(-1);}
}void Date::Print()
{cout << _year << "年" << _month << "月"  << endl;
}void operator<<(ostream& out, const Date& d)
{out << d._year << "/" << d._month << "/" << d._day << endl;
}
//Test.cpp#include"Date.h"int main()
{Date d1(2025, 1, 21);Date d2(2024, 2, 2);cout << d1 ;return 0;
}

//Test.cpp#include"Date.h"int main()
{Date d1(2025, 1, 21);Date d2(2024, 2, 2);cout << d1 << d2 ;return 0;
}

//Date.h#pragma once#include<iostream>
using namespace std;class Date
{friend ostream& operator<<(ostream& out, const Date& d);Date(int year = 1, int month = 1, int day = 1);public:void Print();private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& d);
//Date.cpp#include"Date.h"Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;// 检查日期是否合法if (month < 1 || month > 12|| day < 1 || day > GetMonthDay(year, month)){cout << "非法日期" << endl;// exit(-1);}
}void Date::Print()
{cout << _year << "年" << _month << "月"  << endl;
}ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "/" << d._month << "/" << d._day << endl;return out;
}

//Date.h#pragma once#include<iostream>
using namespace std;class Date
{// 友元声明friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);Date(int year = 1, int month = 1, int day = 1);public:void Print();private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& d);//这里不能加const,因为这是在内部修改让外部拿到这个值
istream& operator>>(istream& in, Date& d);
//Date.cpp#include"Date.h"Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;// 检查日期是否合法if (month < 1 || month > 12|| day < 1 || day > GetMonthDay(year, month)){cout << "非法日期" << endl;// exit(-1);}
}void Date::Print()
{cout << _year << "年" << _month << "月"  << endl;
}ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "/" << d._month << "/" << d._day << endl;return out;
}istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}
//Test.cpp#include"Date.h"int main()
{Date d1(2025, 1, 21);Date d2(2024, 2, 2);cout << d1 << d2;cin >> d1;cout << d1;return 0;
}


四、再谈构造函数

    1.初始化列表

   定义:以一个 冒号开始 ,接着是一个以 逗号分隔的数据成员列表 ,每个 " 成员变量 " 后面跟
一个 放在括号中的初始值或表达式。
class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}private:int _year;int _month;int _day;
};
class A
{
public:A(int a = 0):_a(a){}
private:int _a;
};class Date
{
public:// 初始化列表是每个成员定义的地方// 不管你写不写,每个成员都要走初始化列表Date(int year, int month, int day, int& i): _year(year), _month(month),_a(1),_refi(i){// 赋值_day = day;}private:int _year;  // 每个成员声明int _month = 1 ;int _day = 1;// C++11支持给缺省值,这个缺省值给初始化列表// 如果初始化列表没有显示给值,就用这个缺省值// 如果显示给值了,就不用这个缺省值//这里_day会使用缺省值,而_month不会使用// 下面三个例子必须定义时初始化const int _x = 10;int& _refi;A _a;
};

注意:

   1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)。

   2.类中包含以下成员,必须放在初始化列表位置进行初始化:

       ①引用成员变量     ②const成员变量    ③自定义类型成员(且该类没有默认构造函数时)

   3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,
一定会先使用初始化列表初始化。

   4.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后

次序无关。

总结:

   能用初始化列表就用初始化初始化列表,但有些场景还是需要初始化列表和函数体混着用。


五、explicit关键字

        构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值 的构造函数,还具有类型转换的作用
#include<iostream>
using namespace std;class A
{
public:A(int i)//A(int i):_a(i){cout << "A(int i)" << endl;}private:int _a;
};int main()
{A aa1(1);// 单参数构造函数的隐式类型转换// 用2调用A构造函数生成一个临时对象,再用这个对象去拷贝构造aa2// 编译器会再优化,优化用2直接构造 A aa2 = 2;return 0;
}


A& ref1 = 2;

这里的问题原因是临时对象具有常性,ref不能引用,属于权限的放大,加上const就没有问题了。

const A& ref1 = 2;

#include<iostream>
using namespace std;class B
{
public:B(int b1, int b2)//explicit B(int b1, int b2):_b1(b1), _b2(b2){cout << "B(int b1, int b2)" << endl;}
private:int _b1;int _b2;
};int main()
{// C++11 支持多参数的隐式类型转换B bb1(1, 1);B bb2 = { 2, 2 };const B& ref2 = { 3,3 };return 0;
}


class B
{
public:explicit B(int b1, int b2):_b1(b1), _b2(b2){cout << "B(int b1, int b2)" << endl;}
private:int _b1;int _b2;
};

重点:

        explicit修饰构造函数,禁止类型转换
class A
{
public:explicit A(int i):_a(i){cout << "A(int i)" << endl;}private:int _a;
};class B
{
public:explicit B(int b1, int b2):_b1(b1), _b2(b2){cout << "B(int b1, int b2)" << endl;}
private:int _b1;int _b2;
};

六、生命周期

#include<iostream>
using namespace std;class A
{
public:explicit A(int i):_a(i){cout << "A(int i)" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A& aa)" << endl;}~A(){cout << "~A()" << _a << endl;}
private:int _a;
};int main()
{// 有名对象 特点:生命周期在当前局部域A aa6(6);// 匿名对象。特点:生命周期只在这一行A(7);return 0;
}


总结

        以上就是今天要讲的内容,本文仅仅简单介绍了c++的基础。


http://www.ppmy.cn/devtools/152744.html

相关文章

vue项目创建与运行(idea)

一、安装vue 在安装完node.js后 使用管理员身份运行命令行&#xff0c;在命令行中&#xff0c;执行如下指令&#xff1a; npm install -g vue/cli 这个过程中&#xff0c;会联网下载&#xff0c;可能会耗时几分钟&#xff0c;耐心等待。 以管理员身份运行cmd检查版本 idea创…

Spring Boot 中的 InitializingBean:Bean 初始化背后的故事

在 Spring Boot 应用中&#xff0c;Bean 的生命周期管理至关重要。InitializingBean 接口允许 Bean 在完成属性注入后执行自定义初始化逻辑。本文将深入探讨 InitializingBean 接口在 Spring Boot 中的应用&#xff0c;揭示其工作原理&#xff0c;并分享一些最佳实践&#xff0…

什么是三高架构?

大家好&#xff0c;我是锋哥。今天分享关于【什么是三高架构?】面试题。希望对大家有帮助&#xff1b; 什么是三高架构? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 “三高架构”通常是指高可用性&#xff08;High Availability&#xff09;、高性能&#xff…

日志收集Day001

1.ElasticSearch 作用&#xff1a;日志存储和检索 2.单点部署Elasticsearch与基础配置 rpm -ivh elasticsearch-7.17.5-x86_64.rpm 查看配置文件yy /etc/elasticsearch/elasticsearch.yml&#xff08;这里yy做了别名&#xff0c;过滤掉空行和注释行&#xff09; yy /etc/el…

Nginx正向代理配置

Nginx 正向代理默认只支持 http 协议&#xff0c;不支持 https 协议&#xff0c;需借助 "ngx_http_proxy_connect_module" 模块实现 https 正向代理&#xff0c;详情请参考&#xff1a; https://github.com/chobits/ngx_http_proxy_connect_module 安装Nginx某些模块…

Hadoop特点和HDFS命令

Hadoop的特点 高扩展性: 可以根据数据量的增长进行扩展,可以扩展到数千台机器&#xff0c;每个机器都可以提供本地计算和存储资源 高容错性: 自动保存数据的多个副本&#xff0c;并能够在硬件故障的情况下重新分配计算任务&#xff0c;从而确保系统的高可用性和数据的不丢失。…

nginx实现负载均衡

通过配置 Nginx 实现负载均衡&#xff0c;提高系统的可用性和容错性&#xff1b;分担流量&#xff0c;优化性能和响应速度&#xff1b;便捷地扩展后端服务器&#xff0c;支撑更高的并发&#xff1b;提升系统的安全性&#xff0c;保护后端服务器&#xff1b;灵活地配置负载均衡策…

Oracle 数据库常见字段类型大全及详细解析

在工作期间会遇到数据库建表的业务&#xff0c;经常会使用复制粘帖等操作&#xff0c;而不清楚数据库的字段类型。本文记录了 Oracle 数据库常见字段类型&#xff0c;根据不同的数据需求&#xff0c;可以选择不同的字段类型来存储数据。 文章目录 一、字符类型&#xff08;Char…