zoukankan      html  css  js  c++  java
  • C++ 类

    关于C++中的类的学习笔记

    参考书目:visual c++ 入门经典 第七版 Ivor Horton著 第七、八章

    7.自定义数据类型

    7.1 结构

    特点:结构中的数据类型可以是除了所定义的结构类型以外的任何类型。

    例子:

    //Ex7_01.cpp 
    //Exercising structures in the yard
    #include <iostream>
    using std::cout;
    using std::endl;
    //结构定义
    struct Rectangle
    {
        int left;
        int top;
    
        int right;
        int bottom;
    };
    long area(const Rectangle & aRect)//这里的&有什么作用
    {
        //aRect.bottom = 90;//const 类型不能改变值,会报错
        return (aRect.right - aRect.left)*(aRect.bottom - aRect.top);
    }
    long area1( Rectangle & aRect)//这里去掉const 就可以改变主函数中的变量值了,说明&是对变量的直接引用而不再重新开辟空间
    {
        aRect.bottom = 90;
        return (aRect.right - aRect.left)*(aRect.bottom - aRect.top);
    }
    long area2(Rectangle y)//把&去掉之后 ,尽管可以改变计算结果但是不能改变主函数中的变量值,说明这里重新复制了一个值
    {
        y.bottom = 70;
        return (y.right - y.left)*(y.bottom - y.top);
    }
    int main()
    {
        Rectangle yard{ 0, 0, 100, 120 };//结构的初始化
        Rectangle * pRect{&yard};//指向结构体的指针
        cout << "the right of the yard is :" << pRect->right << endl;//指针对结构体成员的引用
    
        cout << "At the begining ,the bottom of yard is :" << yard.bottom<<endl;
    
        cout << "the area of yard is :" << endl;
        cout << area(yard)<< endl;
    
        cout << "the area1 of yard is :" << endl;
        cout << area1(yard) << endl;
        cout << "when we remove the 'const',the bottom of yard is :" << yard.bottom << endl;
    
        cout << "the area2 of yard is :" << endl;
        cout << area2(yard) << endl;
        cout << "when we remove the '&',the bottom of yard is :" << yard.bottom << endl;
    
        return 0;
    }

    7.2类

    类是用户定义的数据类型,其包含的元素可以是基本数据类型或者其他用户定义的变量,以及函数。

    类的实例叫做对象。

    对象在定义中隐式地包含数据和操作数据的函数,这种思想称作封装。

    类构造函数,是类的特殊函数,在创建新的类对象时调用它。

    例子:

    //定义类及其成员函数
    #include <iostream>
    using std::cout;
    using std::endl;
    class CBox
    {
    public:
        double m_Length{ 1.0 };//这个初始化过程也可以放在构造函数列表中
        double m_Width{ 1.0 };
        double m_Height{ 1.0 };
        //构造函数的定义
        CBox()//名字必须一样,可以有多个对应多种不同的初始化方式
        {
            cout << "default constructor called" << endl;
        }    //这个就代表了使用默认初值,如果这里不进行一个空的定义,在主函数中写CBox box1;会报错
        CBox(double lv, double wv, double hv)
        {
            cout << "constructor called" << endl;
            m_Length = lv;
            m_Width = wv;
            m_Height = hv;
        }
        
        double volume();
    
    };
    double CBox::volume()//在类的外部定义成员函数
    {
        return m_Length*m_Height*m_Width;
    }
    int main()
    {
        CBox box1;
        double boxvolume{ box1.volume() };
        cout << "DEFAULT box1 volume is : " << boxvolume << endl;
    
        //对类的public成员进行重新定义
        box1.m_Height = 18.0;
        box1.m_Length = 2.0;
        cout << "the new box1 volume is : " << box1.volume() << endl;
    
        CBox box2{ 20.0, 80.0, 1};
        cout << "the new box2 volume is : " << box2.volume() << endl;
        return 0;
    
    }

    对于类的构造函数也可以定义成下面的形式

    class CBox
    {
    public:
        double m_Length;
        double m_Width;
        double m_Height;
        //构造函数的另外一种写法,可以简洁的表示上面的过程,效果是一样的
        CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0) :
            m_Length{ lv }, m_Width{ wv }, m_Height{ hv }
        {
            cout << "constructor called " << endl;
        }
        double volume();
    };

    类的析构函数,用来销毁不再需要或者超出其作用域的对象。如果类成员占用的空间是构造函数中动态分配的,就必须自定义析构函数。

    例子:

    //验证析构函数的作用
    //#include <iostream>
    #include <iostream>
    using std::cout;
    using std::endl;
    
    class CBox
    {
    public:
        //析构函数
        ~CBox()
        {
            cout << "Destructor called" << endl;
        }
        
        //构造函数
        explicit CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0) :
            m_Length{ lv }, m_Width{ wv }, m_Height{ hv }
        {
            cout << "constructor called " << endl;
        }
        double volume() const;
        bool compare(const    CBox* pBox) const;
    private:
        double m_Length;
        double m_Width;
        double m_Height;
    
    };
    bool CBox::compare(const    CBox* pBox) const
    {
        if (!pBox)
        {
            return false;
        }
        return this->volume() > pBox->volume();
    }
    double CBox::volume() const//在类的外部定义成员函数
    {
        return m_Length*m_Height*m_Width;
    }
    int main()
    {
        CBox cigar{ 8, 5.0, 1 };
        CBox match{ 2.2, 1.1, 0.5 };
        CBox * pB1{ &cigar };
        CBox * pB2{ &match };
    
        cout << "volume of cigar is " << pB1->volume() << endl;
        cout << "volume of match is " << pB2->volume() << endl;
        cout << "return of the compare() is " << pB1->compare(pB2) << endl;
    
        return 0;
    }

    类模板,类模板本身不是类,而只是编译器用来生成类代码的一种方法。通过指定<T>中T的类型来确定希望生成的类。

    //熟悉类模板的使用
    #include <iostream>
    #include <utility>    //
    #include <algorithm>//MAX MIN
    
    using std::cout;
    using std::endl;
    using namespace std::rel_ops;//这个玩意儿就在utility中
    
    class CBox
    {
    public:
    
        ~CBox()
        {
            //cout << "destructor called" << endl;
        }
        explicit CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0) :
            m_Length{ lv }, m_Width{ wv }, m_Height{ hv }
        {
            cout << "constructor called " << endl;
        
            if (m_Height > m_Length)
            {
                std::swap(m_Height, m_Length);
                std::swap(m_Width, m_Height);
            }
            else if (m_Height > m_Width)
            {
                std::swap(m_Height, m_Width);
            }
        }
            double volume() const
            {
                return m_Length*m_Height*m_Width;
            }
    
            //运算符重载
            bool operator<(const CBox& aBox) const
            {
                return this->volume() < aBox.volume();
            }
            bool operator<(const double value) const
            {
                return this->volume() < value;
            }
            bool operator>(const CBox& aBox) const
            {
                return this->volume() > aBox.volume();
            }
            bool operator>(const double value) const
            {
                return this->volume() > value;
            }
            bool operator==(const CBox& aBox) const
            {
                return this->volume() == aBox.volume();
            }
            CBox operator+(const CBox& aBox) const
            {
                return CBox(std::max(m_Length, aBox.m_Length), std::max(m_Width, aBox.m_Width), m_Height + aBox.m_Height);
            }
            void showBox() const
            {
                cout << m_Length << "" << m_Width << "" << m_Height << endl;
            }
        
    private:
        double m_Length;
        double m_Width;
        double m_Height;
    
    };
    
    //CSamples class template definition,用来存储CBox样本的
    template <typename T> class CSamples
    {
    public:
        CSamples(const T values[], int count);
        CSamples(const T& value);
        CSamples(T&& value);//两个&代表rvalue 引用
        CSamples() = default;
    
        bool add(const T & value);
        bool add(T&& value);
        T max() const;
    private:
        static const size_t maxSamples{ 100 };
        T m_Values[maxSamples];
        int m_Next{};
    };
    //在类模板外部定义其函数
    template <typename T> CSamples <T>::CSamples(const T values[], int count)
    {
        m_Next = count < maxSamples ? count : maxSamples;
        for (int i{}; i < m_Next; i++)
        {
            m_Values[i] = values[i];
        }
    }
    template <typename T> CSamples <T>::CSamples(const T& value)
    {
        m_Next = 1;
        m_Values[0] = value;
    }
    template <typename T> CSamples <T>::CSamples( T && value)
    {
        cout << "move constructor" << endl;
        m_Next = 1;
        m_Values[0] = std::move(value);
    }
    template <typename T> bool CSamples<T>::add(const T& value)
    {
        cout << "add." << endl;
        bool OK{ m_Next < maxSamples };
        if (OK)
            m_Values[m_Next++] = value;
        return OK;
    }
    template <typename T> bool CSamples<T>::add( T&& value)
    {
        cout << "add move" << endl;
        bool OK{ m_Next < maxSamples };
        if (OK)
            m_Values[m_Next++] =std::move(value);
        return OK;
    }
    template <typename T> T CSamples<T>::max() const
    {
        T themax{ m_Values[0] };
        for (int i{ 1 }; i < m_Next; i++)
        {
            if (themax < m_Values[i])
            {
                themax = m_Values[i];
            }
        }
        return themax;
    }
    int main()
    {
        CBox boxes[]{
            CBox{ 8.0, 5.0, 2.0 },
                CBox{ 5, 4, 6 },
                CBox{4,3,3}
        };
        CSamples<CBox> myBoxes{ boxes, _countof(boxes) };//创建CBox类型的类
        CBox maxBox{ myBoxes.max() };
        cout << "the biggest box has a volume of " << maxBox.volume() << endl;
        //加入新的对象
        CSamples<CBox> moreBoxes{ CBox{ 8, 5, 2 } };
        moreBoxes.add(CBox{ 5, 8, 6 });
        moreBoxes.add(CBox{ 4, 3, 3 });
        cout << "the bigest box has a volume of " << moreBoxes.max().volume() << endl;
    
        return 0;
    }
  • 相关阅读:
    DIV指令一般用法
    "Programming"和"Programming"是同一个"Programming"吗?
    对5个国家的名称进行排序详细解析
    Hello World程序
    用 select 实现多选
    浅谈HTTP中Get与Post的区别
    ligerUI 下拉框表格(多选)
    LigerUI自带弹窗返回值例子
    LigerUI Grid服务端分页技术
    jQuery LigerUI 插件介绍及使用之ligerGrid
  • 原文地址:https://www.cnblogs.com/simayuhe/p/5223692.html
Copyright © 2011-2022 走看看