• 《C++程序设计POJ》《WEEK3 类和对象进阶》《复制构造函数》《类型转换构造函数》


    类型转换构造函数 目的
    •实现类型的自动转换 特点
    •只有一个参数
    •不是复制构造函数 编译系统会自动调用  转换构造函数
     建立一个 临时对象 / 临时变量

    class A
    {
    public:
        int a;
        A(int a) :a(a) {}
        A reta()
        {
            return a;
        }
    };
    int main()
    {
        A a(2);
        A b = a.reta(); // 将类型是 int 的变量 赋值给 类型为 A 的对象,调用了 类型转换构造函数
        A c = 3;
        cout<<b.a<<"
    "<<c.a<<endl;
        return 0;
    }
    // 结果是输出2和3
    class Complex {
    public:
    double real, imag;
    Complex( int i ) { //类型转换构造函数
    cout << “IntConstructor called” << endl;
    real = i; imag = 0;
    }
    Complex( double r, double i )
    { real = r; imag = i; }
    };
    int main () {
    Complex c1(7, 8);
    Complex c2 = 12;
    c1 = 9; // 9被自动转换成一个临时Complex对象
    cout << c1.real << "," << c1.imag << endl;
    return 0;
    }
    输出:
    IntConstructor called
    IntConstructor called
    9,0

    复制构造函数

    Complex(const Complex & c)

    X::X(X&)

    X::X(const X &)

    二者选一,后者能以常量对象作为参数

    复制构造函数起作用的三种情况:

    1)当用一个对象去初始化同类的另一个对象时
    Complex c2(c1);
    Complex c2 = c1; //初始化语句,非赋值语句

    Complex c2(c1);

    2)如果某函数有一个参数是类 A 的对象, 那么该函数被调用时,类A的复制构造函数将被调用。

    class A

    {

    public:

    A() { };

    A( A & a)

    {

    cout << "Copy constructor called" <<endl;

    }

    };

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    #if 0
    /*当用一个对象去初始化同类的另一个对象时。*/
    class Complex {
    public:
        double real, imag;
        Complex() {}
        Complex(const Complex &c) {
            real = c.real;
            imag = c.imag;
            cout << "copy constructor called";
        }
    
    };
    int main()
    {
    
        Complex c1;
        Complex c2(c1);
        while (1);
    }
    
    #endif
    /*如果某函数有一个参数是类 A 的对象,
    那么该函数被调用时,类A的复制构造函数将被调用*/
    #if 0
    class A
    {
    public:
        A() {};
        A(A&a) {
            cout << "Copy constructor called" << endl;
        }
    };
    void Func(A a1) {}
    int main()
    {
        A a2;
        Func(a2);
        while (1);
        return 0;
    }
    #endif
    /*如果函数的返回值是类A的对象时,则函数返回时,
    A的复制构造函数被调*/
    class A
    {
    public:
        int v;
        A(int n)
        {
            v = n;
        }
        A(const A & a)
        {
            v = a.v;
            cout << "Copy constructor called" << endl;
        }
    };
    A Func()
    {
        A b(4);
        return b;
    }
    int main()
    {
        cout << Func().v << endl;
        while (1);
        return 0;
    }
    //类型转换构造函数
    #include<iostream>
    using namespace std;
    
    class Complex {
    public:
        double real, imag;
        Complex(int i) { // 类型转换构造函数
            cout << "intConstructor called" << endl;
            real = i;
            imag = 0;
        }
        Complex(double r, double i)
        {
            real = r;
            imag = i;
        }
    
    };
    
    int main()
    {
        Complex c1(7, 8);
        Complex c2 = 12;
        c1 = 9;
        cout << c1.real << "," << c1.imag << endl;
        while (1);
        return 0;
    }

    析构函数 ~

    没有参数和返回值

    对象消亡时,自动被调用

    如果没写析构函数,则编译器生成缺省的析构函数

    析构函数是自动调用的!!!

    //类型转换构造函数
    #include<iostream>
    #include<stdlib.h>
    using namespace std;
    #if 0
    class Complex {
    public:
        double real, imag;
        Complex(int i) { // 类型转换构造函数
            cout << "intConstructor called" << endl;
            real = i;
            imag = 0;
        }
        Complex(double r, double i)
        {
            real = r;
            imag = i;
        }
    
    };
    
    int main()
    {
        Complex c1(7, 8);
        Complex c2 = 12;
        c1 = 9;
        cout << c1.real << "," << c1.imag << endl;
        while (1);
        return 0;
    }
    #endif
    
    #if 0
    class Ctest {
    public:
        ~Ctest()
        {
            cout << "destructor called" << endl;
        }
    };
    
    int main()
    {
        Ctest array[2];
        cout << "End Main" << endl;
        //while (1);
        system("PAUSE");
        return 0;
    }
    #endif
    
    
    class Demo {
        int id;
    public:
        Demo(int i)
        {
            id = i;
            cout << "id=" << id << "constructed" << endl;
        }
        ~Demo()
        {
            cout << "id=" << id << "destructed" << endl;
        }
    };
    
    Demo d1(1); // 全局变量最后消亡
    void Func() {
        static Demo d2(2); // 静态变量在程序结束后消亡
        Demo d3(3);
        cout << "Func" << endl;
    }
    int main()
    {
        Demo d4(4);
        d4 = 6; // 类型转换构造函数,6被自动转换成一个临时Demo对象
        cout << "main" << endl;
        {
            Demo d5(5);
        }//作用域结束,对象消亡
        Func();
        cout << "main ends" << endl;
        //while (1);
        system("PAUSE");
        return 0;
    }

    静态成员变量和静态成员函数 STATIC

    sizeof运算符不会计算静态成员变量

    普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享

    静态成员变量本质是全局变量

    静态成员函数本质上是全局函数

    必须在定义类的文件中对静态成员变量进行一次说明

    普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用与某个对象

    设置静态成员这种机制的目的是将和某些类紧密相关的全局变量和函数写到类里面,看上去像一个整体,易于维护和理解。

    静态成员函数不作用在对象上!!!

    复制构造函数 初始化对象 有坑!!!

    解决方案:写一个复制构造函数

    #include<iostream>
    using namespace std;
    
    class CRectangle
    {
    private:
        int w, h;
        static int nTotalArea;
        static int nTotalNumber;
    public:
        CRectangle(int w_, int h_);
        ~CRectangle();
        static void PrintTotal();
        CRectangle::CRectangle(CRectangle &r)
        {
            w = r.w;
            h = r.h;
            nTotalNumber++;
            nTotalArea += w*h;
        }
    
    };
    
    CRectangle::CRectangle(int w_, int h_)
    {
        w = w_;
        h = h_;
        nTotalNumber++;
        nTotalArea += w*h;
    }
    CRectangle::~CRectangle()
    {
        nTotalNumber--;
        nTotalArea -= w*h;
    }
    void CRectangle::PrintTotal()
    {
        cout << nTotalNumber << "," << nTotalArea << endl;
    }
    
    int CRectangle::nTotalNumber = 0;
    int CRectangle::nTotalArea = 0;
    
    // 必须在定义类的文件中对静态成员变量进行一次说明
    //或初始化。否则编译能通过,链接不能通过。
    int main()
    {
        CRectangle r1(3, 3), r2(2, 2);
        //cout << CRectangle::nTotalNumber;
        CRectangle::PrintTotal();
        r1.PrintTotal();
        while (1);
        return 0;
    
    }
    //在静态成员函数中,不能访问非静态成员变量, 也不能调用非静态成员函数。
    //void CRectangle::PrintTotal()
    //{
    //    cout << w << "," << nTotalNumber << "," << nTotalArea << endl;
    //}
    //CRectangle::PrintTotal();//解释不通,w 到底是属于那个对象的?
  • 相关阅读:
    下载网易云音乐的MV
    如何免费的让网站启用https
    阿里云centos7.x 打开80端口(转)
    阿里云服务器Centos7.4开放80端口的记录
    在线检测域名或者ip的端口是否开放(http://coolaf.com/tool/port)
    重置密码解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    视频录制剪辑工具
    迷你音乐播放器v1.0正式上线!
    网页音乐播放器
    网站菜单CSS
  • 原文地址:https://www.cnblogs.com/focus-z/p/10982566.html
Copyright © 2020-2023  润新知