• C++——构造函数 constructor


    What is constructor

    • C++中,如果你想要创建一个object,有一个函数会自动被调用(不需要programmer显式调用 ),这个函数就是constructor;
    • constructor的写法很独特,其function name必须和class name相同;
    • constructor通过arguments上的差异进而形成ctor的overloading,当然和normal function一样,ctor也可以有default arguments;
    • ctor没有返回值类型;
    • ctor还有个特色功能(ctor独享),initialization list(初始化列表)。与在{ ... }内部赋值private data,initialization list速度会更快。简单讲,一个variable数值的设定有2个阶段,分别是initialization和assignment,initialization先于assignment阶段进行。initialization list就是发生在initialization阶段,{ ... }内部赋值private data属于assignment阶段。如果不使用initialization list表明你主动放弃initialization阶段工作,虽然最后你还是把数值放入到variable,但是时间晚了些,效率差了些;

    默认实参,构造函数,普通函数都有这种性质。

    ctor's overloading

    参考:C++——overloading principle analysis

    关于header file、static、inline、variable hides的一点感想

    我们知道C不允许overloading,C++允许overloading。C++在编译器一侧时别到的函数名与我们看到的函数名是有很大差异的。normal function和ctor的overloading方式差不多。下图事normal function的重载。

     

    注意:黄色部分①②两个ctor则不可以同时存在,①对于的ctor所有形参都有默认参数,这时候就相当于default ctor,和②是一样的效果。编译器在这种情况下无法做出选择。虽然这也是overloading,但是这种overloading让compiler困惑

    常量成员函数

    在函数后头加const,表示函数不会改变调用者的内容,或 形参在函数内部不会改变。

    如果忘记加const,右下角的例子,c1是个常量,而real和imag却有可能改变c1,产生矛盾,编译器报错。

    singleton——把构造函数放在private区

    design patrern中 的一种模式

    构造函数的作用

    ①构造对象:在用类定义一个对象时会自动调用构造函数

    ②初始化对象:类的数据成员往往放在构造函数里面初始化

    ③类型转换:看讲解

    无论C 、C++都是强类型语言,不同类型变量之间不能随便赋值。很多时候我们认为理所当然的赋值都是借助临时变量来实现的。看代码

     1 #include<iostream>
     2 class Test {
     3 public:
     4     Test(int a=0)
     5     {
     6         std::cout << "Create Test Object:" << this<<std::endl;
     7         this->a = a;
     8     }
     9     ~Test()
    10     {
    11         std::cout << "Free Test Object:" << this << std::endl;
    12     }
    13 private:
    14     int a;
    15 };
    16 
    17 int main(int argc, char **argv)
    18 {
    19     Test t1;
    20     t1 = 100;
    21     getchar();
    22     return 0;
    23 }
    View Code

    调试结果

     这里调用了2此构造函数,2次析构函数(析构顺序是栈操作顺序)。输出结果解析

    第1行输出:执行第19行,调用构造函数

    第2行输出:执行第20行,调用构造函数。这里创建了一个临时Test类型对象(C++为了凸显逼格把类类型的变量称为对象),100就是传入构造函数的参数。

    第3行输出:第2行构造完临时对象后,赋值给了对象t1。赋值以后临时对象的生命期就结束了,这里调用析构函数,终结这个临时对象

    第4行输出:第22行return 0返回后调用析构函数,终结对象t1

    画图解释这一过程

    这里面最关键的一个环节就是int类型到Test临时对象转换,int类型要找到一个途径来转换成Test类型。这个途径是什么呢?  构造函数

    而我们代码里面恰恰有这么个构造函数,他的参数就是一个整形。如果我们干掉这个构造函数,换一个不带参数的构造函数(或者干脆不写构造函数,使用默认的),则不能将100赋值给t1

    代码如下

     1 #include<iostream>
     2 class Test {
     3 public:
     4     Test()
     5     {
     6         std::cout << "Create Test Object:" << this << std::endl;
     7         this->a = a;
     8     }
     9     ~Test()
    10     {
    11         std::cout << "Free Test Object:" << this << std::endl;
    12     }
    13 private:
    14     int a;
    15 };
    16 
    17 int main(int argc, char **argv)
    18 {
    19     Test t1;
    20     t1 = 100;
    21     getchar();
    22     return 0;
    23 }
    View Code
     1 #include<iostream>
     2 class Test {
     3 public:
     4     ~Test()
     5     {
     6         std::cout << "Free Test Object:" << this << std::endl;
     7     }
     8 private:
     9     int a;
    10 };
    11 
    12 int main(int argc, char **argv)
    13 {
    14     Test t1;
    15     t1 = 100;
    16     getchar();
    17     return 0;
    18 }
    View Code

    这种情况直接编译不过。错误 C2679 二进制“ = ”: 没有找到接受“int”类型的右操作数的运算符(或没有可接受的转换)。在类型转换的时候,编译器试图寻找能实现转换的构造函数,能找到就执行构造函数生成一个临时对象好用于赋值。找不到就报错。

    额外补充:对于隐式类型转换,生成的临时对象具有const性质。参考 C++——引用

     explicit关键字

    有的时候我们会发现构造函数前面加了个关键字explicit,代码如下

     1 #include<iostream>
     2 class Test {
     3 public:
     4     explicit Test(int a = 0)
     5     {
     6         std::cout << "Create Test Object:" << this << std::endl;
     7         this->a = a;
     8     }
     9     ~Test()
    10     {
    11         std::cout << "Free Test Object:" << this << std::endl;
    12     }
    13 private:
    14     int a;
    15 };
    16 
    17 int main(int argc, char **argv)
    18 {
    19     Test t1;
    20     t1 = (Test)100;
    21     getchar();
    22     return 0;
    23 }
    View Code

    在进行赋值 或 类型转换的时候,如果要借助构造函数是不允许隐式转换的。所以第20行必须强制转换(显式转换)。

  • 相关阅读:
    Codeforces Round #200 (Div. 2) E. Read Time(二分)
    Codeforces Round #160 (Div. 2) D. Maxim and Restaurant(DP)
    TC SRM 593 DIV1 250
    TC SRM 593 DIV2 1000
    HDU 2825 Wireless Password(AC自动机+DP)
    Codeforces Round #203 (Div. 2)
    TC SRM 591 DIV2 1000
    HDU 4758 Walk Through Squares(AC自动机+DP)
    CF 346B. Lucky Common Subsequence(DP+KMP)
    HDU 4753 Fishhead’s Little Game(DFS)
  • 原文地址:https://www.cnblogs.com/kelamoyujuzhen/p/9427292.html
Copyright © 2020-2023  润新知