贵州省公路建设有限公司网站,郑网站建设,wordpress+v4.1,网站怎么看是谁做的C构造函数与析构函数#xff1a;对象生命周期的守护者 引言#xff1a;为什么需要特殊的初始化函数#xff1f; 在C中#xff0c;我们希望使用类对象就像使用基本类型一样方便。比如#xff0c;我们可以这样初始化一个整数或结构体#xff1a; int year 2001; struct th…C构造函数与析构函数对象生命周期的守护者引言为什么需要特殊的初始化函数在C中我们希望使用类对象就像使用基本类型一样方便。比如我们可以这样初始化一个整数或结构体intyear2001;structthing{char*pn;intm;};thing amabob{wodget,-23};但为什么不能这样初始化Stock对象呢Stock hot{Sukie Autos, Inc.,200,50.25};// 错误原因在于数据封装类成员通常是私有的不能直接从外部访问。我们需要一种特殊的方法来初始化对象这就是构造函数的用武之地。构造函数对象的出生证明什么是构造函数构造函数是一种特殊的成员函数在创建对象时自动调用。它的名称与类名相同没有返回类型连void都不是。声明和定义构造函数让我们为Stock类添加构造函数// 构造函数原型Stock(conststd::stringco,longn0,doublepr0.0);// 构造函数定义Stock::Stock(conststd::stringco,longn,doublepr){companyco;if(n0){std::cerrNumber of shares cant be negative; company shares set to 0.\n;shares0;}else{sharesn;}share_valpr;set_tot();// 计算总价值}使用构造函数的两种方式显式调用Stock foodStock(World Cabbage,250,1.25);隐式调用Stockgarment(Furry Mason,50,2.5);与new一起使用Stock*pstocknewStock(Electroshock Games,18,19.0);默认构造函数对象的默认设置默认构造函数是在未提供初始值时使用的构造函数。例如Stock fluffy_the_cat;// 使用默认构造函数重要原则如果没有定义任何构造函数编译器会自动生成一个不做任何事的默认构造函数但如果定义了任何构造函数就必须手动提供默认构造函数定义默认构造函数的两种方法为已有构造函数的参数提供默认值Stock(conststd::stringcoError,intn0,doublepr0.0);重载一个无参数的构造函数Stock();// 默认构造函数推荐做法始终提供对类成员做隐式初始化的默认构造函数。析构函数对象的临终关怀当对象生命周期结束时析构函数自动被调用用于清理资源。定义析构函数析构函数名为~类名没有参数和返回类型// 析构函数原型~Stock();// 析构函数定义Stock::~Stock(){std::coutBye, company!\n;}何时调用析构函数静态对象程序结束时自动对象离开其作用域时动态对象使用delete释放内存时临时对象结束使用时完整示例改进的Stock类头文件 (stock10.h)#ifndefSTOCK10_H_#defineSTOCK10_H_#includestringclassStock{private:std::string company;longshares;doubleshare_val;doubletotal_val;voidset_tot(){total_valshares*share_val;}public:Stock();// 默认构造函数Stock(conststd::stringco,longn0,doublepr0.0);~Stock();// 析构函数voidbuy(longnum,doubleprice);voidsell(longnum,doubleprice);voidupdate(doubleprice);voidshow()const;// const成员函数};#endif实现文件 (stock10.cpp)#includeiostream#includestock10.h// 默认构造函数Stock::Stock(){std::coutDefault constructor called\n;companyno name;shares0;share_val0.0;total_val0.0;}// 带参数的构造函数Stock::Stock(conststd::stringco,longn,doublepr){std::coutConstructor using co called\n;companyco;if(n0){std::coutNumber of shares cant be negative; company shares set to 0.\n;shares0;}else{sharesn;}share_valpr;set_tot();}// 析构函数Stock::~Stock(){std::coutBye, company!\n;}// 其他成员函数实现...使用示例 (usestock2.cpp)#includeiostream#includestock10.hintmain(){{usingstd::cout;coutUsing constructors to create new objects\n;Stockstock1(NanoSmart,12,20.0);// 隐式调用stock1.show();Stock stock2Stock(Boffo Objects,2,2.0);// 显式调用stock2.show();coutAssigning stock1 to stock2:\n;stock2stock1;coutUsing a constructor to reset an object\n;stock1Stock(Nifty Foods,10,50.0);// 创建临时对象并赋值stock1.show();coutDone\n;}// 离开作用域析构函数被调用return0;}C11新特性列表初始化C11允许使用列表初始化语法初始化对象// 匹配带参数的构造函数Stock hot_tip{Derivatives Plus Plus,100,45.0};Stock jock{Sport Age Storage, Inc};// 使用默认参数Stock temp{};// 默认构造函数const成员函数承诺不修改对象对于const对象只能调用不会修改对象状态的成员函数constStock landStock(Kludgehorn Properties);land.show();// 需要show()是const成员函数如何声明const成员函数// 声明voidshow()const;// 定义voidStock::show()const{// 不能修改任何成员变量std::coutCompany: company\n;}最佳实践只要成员函数不修改对象就应将其声明为const。构造函数和析构函数总结表特性构造函数析构函数名称与类名相同~类名返回类型无无参数可以有可重载无调用时机创建对象时销毁对象时主要用途初始化对象清理资源默认版本无自定义构造函数时自动生成始终自动生成可自定义构造函数使用技巧单参数构造函数的隐式转换Bozo dribble44;// 隐式调用Bozo(44)避免隐式转换C11explicitBozo(intn);// 禁止隐式转换关键要点构造函数是对象的出生证明负责初始化工作析构函数是对象的临终关怀负责清理工作如果定义了任何构造函数必须手动提供默认构造函数使用const成员函数保证不修改对象状态C11的列表初始化让对象创建更简洁构造函数可以使用默认参数减少重载数量记住良好的类设计应该让对象生得正确死得干净。构造函数和析构函数正是实现这一目标的关键工具