首页
Search
1
C# 击败 Python 成为 TIOBE 2025 年度编程语言,业界地位仍面临 Java 生态优势挑战
13 阅读
2
IT、互联网行业就业热度依旧!这份调研报告出炉
11 阅读
3
韩报告:中国IT行业需求恢复有望推动韩国对华出口增加
7 阅读
4
巫妖易语言+js逆向+安卓逆向,巫妖易语言,探索JS逆向与安卓逆向的深度应用
5 阅读
5
全国信息学奥赛入门级竞赛被举报泄题,中国计算机学会:收到举报,正在调查
5 阅读
采集分类
技术分享
工具分享
登录
Search
私人云
累计撰写
1,121
篇文章
累计收到
3
条评论
首页
栏目
采集分类
技术分享
工具分享
页面
搜索到
1121
篇与
的结果
2026-02-07
C++ 友元探讨
什么是友元?友元声明出现在类内部,它可以授予函数或其他类访问友元声明的类的私有成员和保护成员的权限。(https://en.cppreference.com/w/cpp/language/friend.html)。可能需要注意的点:友元声明在类内部,但是具体出现的位置不限,也不受所在区域访问控制级别(即 public,private或protected)的约束。一般来说,最好在类定义开始或结束前的位置集中声明友元友元可以是函数(包括类的成员函数)或者类友元可以访问声明友元的类的私有成员和保护成员友元不可继承、不可传递、不是相互的(friendship isn’t inherited, transitive, or reciprocal)。可以如下解释:不可继承:除非额外声明, 否则我的友元的派生类不会自动成为我的友元不可传递:除非额外声明,我的友元的友元不会自动成为我的友元不是相互的:除非额外声明,我不会自动成为我的友元的友元一个简单的友元示例:#include <iostream>using namespace std;// 前向声明类,用于友元成员函数的声明class MyClass;// 声明一个类,其成员函数将被作为友元class FriendClassFunction {public:void accessPrivateAndProtected(MyClass& obj); // 成员函数访问MyClass的私有和保护数据};// 声明一个类, 将类作为友元class FriendClass2 {public:void accessPrivateAndProtected(MyClass& obj); // 成员函数访问MyClass的私有和保护数据};// 主类定义class MyClass {private:int privateData;protected:int protectedData;public:MyClass(int priv, int prot) : privateData(priv), protectedData(prot) {}// 声明友元函数(普通全局函数)friend void friendFunction(MyClass& obj);// 声明特定成员函数为友元(FriendClass的成员函数)friend void FriendClassFunction::accessPrivateAndProtected(MyClass& obj);// 声明友元类(FriendClass的所有成员函数均可访问私有和保护成员)friend class FriendClass2;};// 友元函数定义(非成员函数)void friendFunction(MyClass& obj) {cout << "friendFunction access private: " << obj.privateData << endl;cout << "friendFunction access protected: " << obj.protectedData << endl;}// FriendClass成员函数的定义void FriendClassFunction::accessPrivateAndProtected(MyClass& obj) {cout << "FriendClassFunction::accessPrivateAndProtected access private: " << obj.privateData << endl;cout << "FriendClassFunction::accessPrivateAndProtected access protected: " << obj.protectedData << endl;}// FriendClass成员函数的定义void FriendClass2::accessPrivateAndProtected(MyClass& obj) {cout << "FriendClass2 access private: " << obj.privateData << endl;cout << "FriendClass2 access protected: " << obj.protectedData << endl;}int main() {MyClass obj(42, 100);// 调用友元函数friendFunction(obj);// 调用类成员函数FriendClassFunction fcf;fcf.accessPrivateAndProtected(obj);// 调用友元类的成员函数FriendClass2 fc2;fc2.accessPrivateAndProtected(obj);return 0;}/*编译指令: g++ -std=c++11 simple_friend.cpp -o simple_friend操作系统: centos7.6gcc版本: 4.8.5输出:friendFunction access private: 42friendFunction access protected: 100FriendClassFunction::accessPrivateAndProtected access private: 42FriendClassFunction::accessPrivateAndProtected access protected: 100FriendClass2 access private: 42FriendClass2 access protected: 100*/友元会破坏封装吗?这部分的观点主要来自于C++标准官方网站的FAQ(https://isocpp.org/wiki/faq/friends)。这里给出的结论是:不会。“友元” 是一种显式授予访问权限的机制,就像成员一样。让谁成为友元的控制权完全在开发者手上,不能在不修改类源代码的情况下授予其他类或函数对类的访问权限(像public的成员那样,不修改类的源代码,使用者就可以拥有对其的访问权限)。可以将友元函数作为类的公共成员函数的语法变体,或者可以尝试把友元函数视为类的公共接口的一部分。很明显,友元函数并不会比类的public函数对封装有更多的破坏。当需要给外界提供一个访问私有成员和保护成员的方法时,将成员改成公共访问属性无疑是最差的做法。而使用友元的方法起码不会比使用类的公共成员函数(如get()/set()) 对封装性有更多的破坏。相较于类的公共成员函数,友元的优缺点有哪些?这部分的观点主要来自于C++标准官方网站的FAQ(https://isocpp.org/wiki/faq/friends)。诚如前所述,将友元函数作为类的公共成员函数的语法变体。那相对于类的公共成员函数,友元的优缺点在哪里?优点:在接口设计选项方面提供了一定程度的自由。友元函数的调用方式类似于 f(x),而成员函数的调用方式类似于 x.f()。因此,能够在成员函数(x.f())和友元函数(f(x))之间进行选择,使设计人员能够选择可读性最高的语法,从而降低维护成本。缺点:友元函数不能是虚函数,也就无法直接实现动态绑定。当需要进行动态绑定时,需要添加额外的代码,通常是需要声明一个 protected 虚函数 。如下示例: class Base {public:friend void f(Base& b);// ...protected:virtual void do_f(); // protected 虚函数, 被虚函数调用, 实现多态// ...};inline void f(Base& b){b.do_f(); // 如果 b 实际上是 Derived 类 的对象,则调用Derived::do_f();而f一直是Base类的友元,不是Derived类的友元。如果是公共成员函数,则直接实现一个虚函数即可}class Derived : public Base {public:// ...protected:virtual void do_f(); // 覆盖 f(Base& b) 行为// ...};void userCode(Base& b){f(b);}什么时候使用成员函数?什么时候声明友元函数?这部分的观点主要来自于C++标准官方网站的FAQ(https://isocpp.org/wiki/faq/friends)。尽量使用成员函数,必须的时候使用友元。比如以下场景下友元更有优势:类的成员函数有一个隐式的第一个参数——this指针,而友元函数没有,所有参数都必须显示声明。这一点在运算符重载中尤其有用,特别是当需要保证运算的交换律时。比如当想重载乘法运算符 *,使得一个 Complex(复数)对象既可以与一个 double(双精度浮点数)相乘,也可以反过来。运算符重载为类的成员函数,double * complex这种写法就无法直接实现;而将运算符重载为友元函数,可以自由定义两个参数的顺序。/*使用成员函数, 无法实现double * complex*/#include <iostream>using namespace std;class Complex {private:double real;double imag;public:Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}// 成员函数重载运算符:c * 2.5 有效Complex operator*(const double& d) const {return Complex(real * d, imag * d);}void display() const {cout << "(" << real << ", " << imag << "i)" << endl;}};int main() {Complex c1(3.0, 4.0);Complex c2 = c1 * 2.5; // 正确:等价于 c1.operator*(2.5)c2.display(); // 输出 (7.5, 10i)// Complex c3 = 2.5 * c1; // 错误!2.5.operator*(c1) 不成立return 0;}/*编译指令: g++ -std=c++11 complex_multi_member.cpp -o complex_multi_member操作系统: centos7.6gcc版本: 4.8.5输出:(7.5, 10i)*/```/*使用友元, 可以实现double * complex*/#include <iostream>using namespace std;class Complex {private:double real;double imag;public:Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}// 声明友元函数。注意,两个参数都需要显式列出。friend Complex operator*(const Complex& c, const double& d);friend Complex operator*(const double& d, const Complex& c);void display() const {cout << "(" << real << ", " << imag << "i)" << endl;}};// 定义友元函数:Complex * doubleComplex operator*(const Complex& c, const double& d) {return Complex(c.real * d, c.imag * d);}// 定义另一个友元函数:double * Complex// 注意这里 double 是第一个参数,Complex 是第二个参数。// 这正是成员函数无法实现的。Complex operator*(const double& d, const Complex& c) {// 利用乘法交换律,直接调用上一个函数即可return c * d;}int main() {Complex c1(3.0, 4.0);Complex c2 = c1 * 2.5; // 正确:调用 operator*(c1, 2.5)c2.display(); // 输出 (7.5, 10i)Complex c3 = 2.5 * c1; // 正确:调用 operator*(2.5, c1)c3.display(); // 输出 (7.5, 10i)return 0;}/*编译指令: g++ -std=c++11 complex_multi_friend.cpp -o complex_multi_friend操作系统: centos7.6gcc版本: 4.8.5输出:(7.5, 10i)(7.5, 10i)*/在《Effective C++ (中文版)》(第三版) 的第24条中有个类似的例子,按照其中的介绍,上面的例子应该实现为:/*使用非友元非member函数, 可以实现double * complexeffective C++ 中的做法*/#include <iostream>using namespace std;class Complex {private:double real;double imag;public:Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}void display() const {cout << "(" << real << ", " << imag << "i)" << endl;}double getReal() const { return real; }double getImag() const { return imag; }};// 定义非成员非友元函数:Complex * doubleComplex operator*(const Complex& c, const double& d) {return Complex(c.getReal() * d, c.getImag() * d);}// 定义另一个非成员非友元函数:double * Complex// 注意这里 double 是第一个参数,Complex 是第二个参数。// 这正是成员函数无法实现的。Complex operator*(const double& d, const Complex& c) {// 利用乘法交换律,直接调用上一个函数即可return c * d;}int main() {Complex c1(3.0, 4.0);Complex c2 = c1 * 2.5; // 正确:调用 operator*(c1, 2.5)c2.display(); // 输出 (7.5, 10i)Complex c3 = 2.5 * c1; // 正确:调用 operator*(2.5, c1)c3.display(); // 输出 (7.5, 10i)return 0;}/*编译指令: g++ -std=c++11 complex_multi_friend_effective.cpp -o complex_multi_friend_effective操作系统: centos7.6gcc版本: 4.8.5输出:(7.5, 10i)(7.5, 10i)*/《Effective C++ (中文版)》(第三版) 中建议不要使用friend。但是它使用了公共成员函数,按照前面的观点,使用友元的方法起码不会比使用类的公共成员函数(如get()/set()) 对封装性有更多的破坏,因此这种实现封装性也没有更好。至于在具体实现中,采用什么样的方式就见仁见智了。但是个人感觉大多数情况下到了这一步是使用友元还是使用成员函数都不应该成为纠结的重点,因为这些都不会对程序有什么重大的影响,比如导致编译速度过低、运行问题定位困难等。可能把精力放在对程序影响更大的地方是更好的选择。友元使用实例运算符重载(比如 <<,>>),这种情况其实提供公共接口也可以单元测试对私有成员进行测试,这种情况其实提供公共接口或者修改测试方案应该也可以CRTP(Curiously Recurring Template Pattern,奇异递归模板模式) 实现单例模式。这个后面详细介绍CRTP(Curiously Recurring Template Pattern,奇异递归模板模式) 是一种C++模板编程技术,其中类通过继承一个以自身作为模板参数的模板基类来实现静态多态。其基本形式为:template <typename Derived>class Base {// 基类实现};class Derived : public Base<Derived> {// 派生类实现};使用CRTP来实现单例模式,简单的测试代码如下:#include <iostream>template <typename T>class Singleton {public:// 删除拷贝构造和赋值操作,确保单例唯一性Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;// 全局访问点,返回唯一实例的引用static T& GetInstance() {static T instance; // C++11保证静态局部变量初始化线程安全return instance;}protected:Singleton() = default; // 构造函数受保护,防止外部直接实例化virtual ~Singleton() = default; // 虚析构函数,确保正确析构};// 具体的单例类,例如一个日志管理器class Logger : public Singleton<Logger> {// 声明友元,允许Singleton<Logger>访问Logger的私有构造函数friend class Singleton<Logger>;private:Logger() { std::cout << "Logger instance created.\n"; } // 构造函数私有~Logger() override = default;public:void log(const std::string& message) {std::cout << "Log: " << message << std::endl;}};// 使用示例int main() {Logger& logger1 = Logger::GetInstance();logger1.log("First message");Logger& logger2 = Logger::GetInstance(); // logger2 和 logger1 是同一个实例logger2.log("Second message");// 验证是同一个实例std::cout << "Are they the same instance? " << (&logger1 == &logger2 ? "Yes" : "No") << std::endl; // 输出 Yesreturn 0;}/*编译指令: g++ -std=c++11 crtp_singleton.cpp -o crtp_singleton操作系统: centos7.6gcc版本: 4.8.5输出:Log: First messageLog: Second messageAre they the same instance? Yes*/使用CRTP实现单例模式在系统中存在多个需要单例的类时具有以下优势:任何需要成为单例的类只需继承自 Singleton<T>即可自动获得单例的全部能力,可以减少重复代码保证所有单例实现逻辑一致而这里面使用到了友元,目前我还没有发现其他的比较好的不用友元的替代方案。参考腾讯元宝-deepseek(https://yuanbao.tencent.com/)和deepseek官方网站(https://www.deepseek.com/)辅助https://en.cppreference.com/w/cpp/language/friend.html《C++ Primer (中文版)》 第5版,7.2.1 节 友元;7.3.4节 友元再探C++ FAQ(Frequently Asked Questions):https://isocpp.org/wiki/faq/friends。这是很多观点的主要来源。C++ FQA(frequently questioned answers): https://yosefk.com/c++fqa/friend.html#fqa-14.2。说实在的,看了一下,感觉用处不是很大。在stackoverflow的相关问题下也见过批评这部分的。https://stackoverflow.com/questions/17434/when-should-you-use-friend-in-c欢迎关注公众号: 只做人间不老仙
2026年02月07日
0 阅读
0 评论
0 点赞
2026-02-07
江苏盐城:-10°C天气下,大叔跳入冰河救人!
数九寒天,河水冰冷刺骨,一辆轿车四轮朝天翻在河中,驾驶员被困。危急时刻,响水县富达临港供水有限公司职工王春挺身而出,冒着严寒毫不犹豫跳入冰冷的河中,在响水县银河居委会居民陆俊潼的协助下,救起落水者。1月28日,盐城市见义勇为基金会送奖上门,颁发见义勇为奖金,对他们奋不顾身救人的行为表示肯定。左二是陆俊潼、左三是王春。1月20日9时许,响水县室外气温低至-10℃,刚从工厂下夜班的胡小豪(化名)驾车行至响陈路时,因雪后路面湿滑加之操作不当,车辆失控冲入河道中,车身瞬间翻转,倒扣河中。被困车内的胡小豪多次自救失败,河水迅速涌入,绝望之际他只能奋力拍打车窗。生死关头,路过此处的王春目睹了事故全过程,他来不及多想,毅然跳入河水中,奋力游向沉车,此时河水冰冷刺骨、冰层薄脆。“不要怕,你把手伸过来!”冰冷的河水很快浸透了王春的衣物,寒意瞬间侵袭全身,但他咬紧牙关,用尽全力拍打车窗,经过不断尝试,终于将车门拉开,将车内被困的胡小豪拖拽出来,在岸边过路群众的配合下,将胡小豪拉上岸。展开全文上岸后,王春已冻得浑身发紫、嘴唇颤抖,却仍不忘询问被困人员的状况,为防止胡小豪出现失温风险,好心人陆俊潼与王春一同将其带到王春上班的厂区,借助空调为其取暖。好在救助及时,胡小豪身体并无大碍。1月26日,响水县公安局确认了王春和陆俊潼的见义勇为行为。王春:“我当时什么都没想,就是搭把手的事,只不过受点冻,费了点力气而已。”据了解,王春今年58岁,是一名共产党员。谈及此次救人之举,他朴实地表示,这只是微不足道的小事。返回搜狐,查看更多
2026年02月07日
0 阅读
0 评论
0 点赞
2026-02-07
石川祐希12分 男排欧冠豪取四连胜 佩鲁贾稳居C组榜首
广告 石川祐希12分 男排欧冠豪取四连胜 佩鲁贾稳居C组榜首 4:39 广告 广告 广告 了解详情 > 会员跳广告 首月9.9元 秒后跳过广告 开通搜狐视频黄金会员,尊享更高品质体验!1080P及以上画质仅为黄金会员专享> 开通/续费会员 抱歉,您观看的视频加载失败 请检查网络连接后重试,有话要说?请点击 我要反馈>> 正在切换清晰度... 播放 按esc可退出全屏模式 00:00 00:00 09:01 广告 只看TA 高清 倍速 剧集 字幕 下拉浏览更多 5X进行中 炫彩HDRVIP尊享HDR视觉盛宴 超清 720P 高清 540P 2.0x 1.5x 1.25x 1.0x 0.8x 50哎呀,什么都没识别到反馈循环播放 跳过片头片尾 画面色彩调整 AI明星识别 视频截取 跳过片头片尾 是 | 否色彩调整亮度标准饱和度100对比度100恢复默认设置关闭复制全部log北京时间1月29日,2025-2026赛季欧洲冠军联赛男排第四轮第四回合较量继续进行,在C组一场焦点战中,意大利劲旅佩鲁贾(Sir Sicoma Monini Perugia)坐镇主场,以3-1力克来访的西班牙拉斯帕尔马斯(Guaguas Las Palmas),四局比分为26-24、25-19、21-25、25-20。至此,佩鲁贾豪取小组赛四连胜,积11分独占鳌头,领先排名第二的柏林三分。比赛一开始,双方就展开激烈缠斗。首局双方多次交换领先,比分一直胶着至最后阶段。佩鲁贾凭借乌克兰主攻普罗特尼斯基的发球直接得分取得开局优势,随后日本主攻石川祐希表现活跃,与队友本塔拉接连得手,带动全队进攻节奏。但西班牙队顽强应战,老将尼古拉斯·布鲁诺与胡安托雷纳频频得分,将比分追至23平,关键时刻,普罗特尼斯基封死布鲁诺的进攻,帮助主队26-24惊险先下一城。第二局佩鲁贾火力全开,开局由普罗特尼斯基和洛塞尔连续强攻建功,建立起7-4的领先优势。尽管拉斯帕尔马斯一度追平,但佩鲁贾队长詹内利调度得当,副攻鲁索与洛塞尔轮番打出快攻和拦网,彻底压制住对手节奏。本塔拉再度打出Ace球,佩鲁贾逐渐将比分拉开至21-17,最终以25-19再下一局。展开全文第三局风云突变,拉斯帕尔马斯全队爆发,开局一波4-0打懵主队。华胡安托雷纳连续强攻得手,配合布鲁诺在后排吊球穿插,迅速将比分拉大至10-3。佩鲁贾暂停后逐渐找回节奏,普罗特尼斯基、鲁索与石川祐希接连得分,曾将差距缩小至13-14。但西班牙人没有手软,关键分上连续抓防反,最终以25-21扳回一局。第四局再度进入拉锯战,双方前半局打得难解难分。关键时刻,佩鲁贾副攻洛塞尔打出连续快攻,外加对手失误送分,主队14-12领先。进入尾声,普罗特尼斯基与本塔拉在进攻端持续施压,成功拦死对手,比分逐渐拉开。最终由副攻克罗萨托扣杀定音,佩鲁贾以25-20拿下比赛。本场比赛,佩鲁贾男排5人上双,主攻普罗特尼斯基荣膺全场MVP,他全场砍下16分(31扣13中1拦2发),本塔拉同样拿到16分(26扣12中1拦3发),洛塞尔12分(10扣7中5拦),石川祐希12分(26扣11中1拦),鲁索10分(14扣9中1拦)。拉斯帕尔马斯3人上双,胡安托雷纳17分(25扣17中),布鲁诺17分(31扣15中1拦1发),贝泽拉16分(27扣16中)。目前C组战罢四轮,佩鲁贾四战全胜积11分,暂列小组第一,德国劲旅柏林8分名列次席,拉斯帕尔马斯与芬兰的图伦特位居其后。感谢您的阅读、返回搜狐,查看更多
2026年02月07日
0 阅读
0 评论
0 点赞
2026-02-07
Stein:热火能为字母哥提供的最佳报价是希罗+韦尔+2首轮+其他
直播吧01月30日讯 据NBA知名记者Marc Stein报道,迈阿密热火与明尼苏达森林狼正全力追逐扬尼斯-阿德托昆博,其中热火被视作最具竞争力的追求者。 Stein写道:“你一定已经注意到,热火队对于达米安·利拉德、凯文·杜兰特,以及最近的贾·莫兰特等球员,热火始终没有拿出他们压箱底的最佳交易方案。迈阿密一直在保留他们最令人垂涎的选秀资产,就是为了等待追逐这样一位合适的全明星球员。而现在,时机似乎到了。 热火队所能提供的最佳报价,预计将是一个以威斯康星州本地人泰勒·希罗为核心,辅以崭露头角的大个子球员克雷尔·韦尔,外加2030年和2032年可交易的首轮选秀权的组合包。热火队交易方案中可能包含的其他球员有:特里·罗齐尔的到期合同(前提是联盟办公室在等待一项联邦赌博调查结果期间允许这样做,该调查导致罗齐尔自去年十月起被无限期停职),以及雄鹿队长期以来的交易目标安德鲁·维金斯。” 【来源:直播吧】
2026年02月07日
0 阅读
0 评论
0 点赞
2026-02-07
输广厦发布会!邱彪强调学习+疲惫,评价王证给高度评价检验自己
来源: CBA常规赛,广厦86-77战胜山东。赛后邱彪表示:跟卫冕冠军队伍打我们姿态摆的很正,抱着学习和拼搏的心态去打。看到双方非常疲惫哦,健健康康打完最后两场比赛。特别是国家队队员还有新任务,把后面比赛打好。 健康是必要的,学习也是必要的,但邱彪在这场比赛的用人是大家都没有想到的。高诗岩休息了,但为什么让于德豪在首发?如果让谢智杰在首发,球队后场也不至于那么劣势。再加上陶汉林状态好不重用,最后时刻放弃克里斯,这都是让人懵逼的举动。而这场比赛山东完全有取胜的希望,就是用人出现了大问题,不然他们完全可以拼一下。 邱彪还提到了王证:投篮气质非常不错,他现在可能第一年上篮身体单薄,但是他投篮这块非常好。尤其上一场3分钟拿了11分,希望通过跟冠军球队的实战中总结东西,去检验自己,找到差距。他在进攻端的自信心确实没什么问题,这两场比赛也可以看出。只要有机会,他就会大胆出手,这是一个射手的特性。只要稳定性保持住了,他肯定是未来之星。 不过他因为对抗不行,防守端的发挥不是很好,这肯定是他需要弥补的。特别是这场打了27分钟的情况下,队友需要帮他进行协防。同时在面对高尺寸的球员时,他在进攻端的稳定性也差点意思。不过年轻球员就是需要通过失败去找差距,这也是他们的必经之路,也希望他在窗口期继续强化自己,看看能不能成为顶级3D球员。
2026年02月07日
0 阅读
0 评论
0 点赞
1
...
68
69
70
...
225