提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|行业资讯|编辑:龚雪|2016-04-26 09:15:59.000|阅读 305 次
概述:本文主要为大家介绍C++ 11中对类新增的特性,欢迎品鉴!
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
在我们没有显式定义类的复制构造函数和赋值操作符的情况下,编译器会为我们生成默认的这两个函数:默认的赋值函数以内存复制的形式完成对象的复制。
这种机制可以为我们节省很多编写复制构造函数和赋值操作符的时间,但是在某些情况下,比如我们不希望对象被复制,在之前我们需要将复制构造函数和赋值操作符声明为private,现在可以使用delete关键字实现:
class X { // … X& operator=(const X&) = delete; // 禁用类的赋值操作符 X(const X&) = delete; };
显式地使用default关键字声明使用类的默认行为,对于编译器来说明显是多余的,但是对于代码的阅读者来说,使用default显式地定义复制操作,则意味着这个复制操作就是一个普通的默认的复制操作。
派生类中可以不实现基类虚函数,也可以实现,但不使用virtual关键字;这很容易给人造成混淆,有时为了确认某个函数是否是虚函数,我们不得不追溯到基类查看;C++11引入了两个新的标识符: override和final。override,表示函数应当重写基类中的虚函数。(用于派生类的虚函数中)final,表示派生类不应当重写这个虚函数。(用于基类中)
struct B { virtual void f(); virtual void g() const; virtual void h(char); void k(); // non-virtual virtual void m() final; }; struct D : B { void f() override; // OK: 重写 B::f() void g() override; // error: 不同的函数声明,不能重写 virtual void h(char); // 重写 B::h( char ); 可能会有警告 void k() override; // error: B::k() 不是虚函数 virtual void m(); // error: m()在基类中声明禁止重写 };
有了它们虚函数用起来更为安全,也更好阅读。
在C++98中,如果你想让两个构造函数完成相似的事情,可以写两个大段代码相同的构造函数,或者是另外定义一个init()函数,让两个构造函数都调用这个init()函数。例如:
class X { int a; // 实现一个初始化函数 validate(int x) { if (0<x && x<=max) a=x; else throw bad_X(x); } public: // 三个构造函数都调用validate(),完成初始化工作 X(int x) { validate(x); } X() { validate(42); } X(string s) { int x = lexical_cast<int>(s); validate(x); } // … };
这样的实现方式重复罗嗦,并且容易出错。
在C++0x中,我们可以在定义一个构造函数时调用另外一个构造函数:
class X { int a; public: X(int x) { if (0<x && x<=max) a=x; else throw bad_X(x); } // 构造函数X()调用构造函数X(int x) X() :X{42} { } // 构造函数X(string s)调用构造函数X(int x) X(string s) :X{lexical_cast<int>(s)} { } // … };
C++11提供了将构造函数晋级的能力:比如以下这个示例,基类提供一个带参数的构造函数,而派生类没有提供;如果直接使用D1 d(6);将会报错;通过将基类构造函数晋级,派生类中会隐式声明构造函数D1(int);需要注意的是,晋级后的基类构造函数是无法初始化派生类的成员变量的,所以如果派生类中有成员变量,需要使用初始化列表初始化;
struct B1 { B1(int) { } }; struct D1 : B1 { using B1::B1; // 隐式声明构造函数D1(int) // 注意:在声明的时候x变量已经被初始化 int x{0}; }; void test() { D1 d(6); // d.x的值是0 }
在C++98标准里,只有static const声明的整型成员能在类内部初始化,并且初始化值必须是常量表达式。这些限制确保了初始化操作可以在编译时期进行。
class X { static const int m1 = 7; // 正确 const int m2 = 7; // 错误:无static static int m3 = 7; // 错误:无const static const string m5 = “odd”; //错误:非整型 };
C++11的基本思想是,允许非静态(non-static)数据成员在其声明处(在其所属类内部)进行初始化。这样,在运行时,需要初始值时构造函数可以使用这个初始值。现在,我们可以这么写:
class A { public: int a = 7; }; 它等同于使用初始化列表: class A { public: int a; A() : a(7) {} };
单纯从代码来看,这样只是省去了一些文字输入,但在有多个构造函数的类中,其好处就很明显了:
class A { public: A(): a(7), b(5), hash_algorithm(“MD5″), s(“Constructor run”) {} A(int a_val) : a(a_val), b(5), hash_algorithm(“MD5″), s(“Constructor run”) {} A(D d) : a(7), b(g(d)), hash_algorithm(“MD5″), s(“Constructor run”) {} int a, b; private: // 哈希加密函数可应用于类A的所有实例 HashingFunction hash_algorithm; std::string s; // 用以指明对象正处于生命周期内何种状态的字符串 };
可以简化为:
class A { public: A() {} A(int a_val) : a(a_val) {} A(D d) : b(g(d)) {} int a = 7; int b = 5; private: //哈希加密函数可应用于类A的所有实例 HashingFunction hash_algorithm{“MD5″}; //用以指明对象正处于生命周期内何种状态的字符串 std::string s{“Constructor run”};
在C++98中,我们自定义的类,会默认生成拷贝赋值操作符函数和拷贝赋值函数以及析构函数;在C++11中,依赖于新增的move语义,默认生成的函数多了2个移动相关的:移动赋值操作符( move assignment )和移动构造函数( move constructor );BS建议,如果你显式声明了上述 5 个函数或操作符中的任何一个,你必须考虑其余的 4 个,并且显式地定义你需要的操作,或者使用这个操作的默认行为。
一旦我们显式地指明( 声明 , 定义 , =default , 或者 =delete )了上述五个函数之中的任意一个,编译器将不会默认自动生成move操作。一旦我们显式地指明( 声明 , 定义 , =default , 或者 =delete )了上述五个函数之中的任意一个,编译器将默认自动生成所有的拷贝操作。但是,我们应该尽量避免这种情况的发生,不要依赖于编译器的默认动作。
如果你声明了上述 5 个默认函数中的任何一个,强烈建议你显式地声明所有这 5 个默认函数。例如:
template<class T> class Handle { T* p; public: Handle(T* pp) : p{pp} {} // 用户定义构造函数: 没有隐式的拷贝和移动操作 ~Handle() { delete p; } Handle(Handle&& h) :p{h.p} { h.p=nullptr; }; // transfer ownership Handle& operator=(Handle&& h) { delete p; p=h.p; h.p=nullptr; } // 传递所有权 Handle(const Handle&) = delete; // 禁用拷贝构造函数 Handle& operator=(const Handle&) = delete; // ... };
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn
文章转载自:慧都控件网通过提供强大的3D CAD数据访问工具并适用于桌面、移动和Web的高级环境3D可视化发动机,HOOPS在提升造船设计和制造流程的效率方面发挥了重要作用。
HOOPS Luminate在汽车行业中的应用具有广泛的潜力和深远的影响。它通过提供高效的3D可视化、虚拟装配与拆解、性能分析、客户定制等功能,帮助汽车制造商在设计、生产和销售过程中提升效率、降低成本并提高产品质量。
在不断发展的软件开发世界中,使工具和框架与最新的平台版本保持同步至关重要,欢迎查阅~
全球航运业对国际贸易至关重要,全球 90% 以上的商品通过海运运输。准确监控和控制这些集装箱的移动对于维持高效的供应链至关重要。手动输入集装箱号码是这一程序的关键部分,它带来了相当大的挑战,例如人为错误和效率低下。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@cahobeh.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢