C++基础学习笔记 day03

C++基础学习笔记 day03_第1张图片

1. 设计立方体类

设计立方体类(Cube),求立方体的面积(2*a*b + 2*a*c + 2*b*c)和体积(a*b*c),分别用全局函数和成员函数判断两个立方体是否相等?

#include 
using namespace std;

/*
设计立方体类(Cube)
求立方体的面积(2*a*b + 2*a*c + 2*b*c)和体积(a*b*c)
分别用全局函数和成员函数判断两个立方体是否相等?
*/

class Cube
{
public:
        // 设置长宽高
        void setL(int l)
        {
                m_L = l;
        }
        void setW(int w)
        {
                m_W = w;
        }
        void setH(int h)
        {
                m_H = h;
        }

        // 获取长宽高
        int getL()
        {
                return m_L;
        int getW()
        {
                return m_W;
        }
        int getH()
        {
                return m_H;
        }

        // 求立方体的面积
        void getCubeS()
        {
                int S = 2*m_L*m_W + 2*m_L*m_H + 2*m_W*m_H;
                cout << "立方体的面积为:" << S << endl;
        }

        // 求立方体的体积
        void getCubeV()
        {
                int V = m_L*m_W*m_H;
                cout << "立方体的体积为:" << V << endl;
        }

        // 通过成员函数判断是否相等
        bool compareCubeByClass( Cube &cub )
        {
                bool ret = ( cub.getL() == m_L && cub.getW() == m_W && cub.getH() == m_H );
                return ret;
        }

private:
        int m_L; // 长
        int m_W; // 宽
        int m_H; // 高
};

// 全局函数判断 两个立方体是否相等
bool compareCube( Cube &cub1, Cube &cub2 )
{
        if( cub1.getL() == cub2.getL() && cub1.getW() == cub2.getW() && cub1.getH() == cub2.getH() )
        {
                return true;
        }
        return false;
}

void test01()
{
        Cube c1;

        c1.setL(10);
        c1.setW(10);
        c1.setH(10);

        c1.getCubeS(); // 600
        c1.getCubeV(); // 1000
        // 通过全局函数判断两个立方体是否相等
        Cube c2;

        c2.setL(10);
        c2.setW(10);
        c2.setH(10);

        bool ret = compareCube( c1, c2 );
        if( ret == true )
        {
                cout << "c1和c2两个立方体相等" << endl;
        }
        else
        {
                cout << "c1和c2两个立方体不相等" << endl;
        }

        // 通过成员函数判断两个立方体是否相等
        bool ret2 = c1.compareCubeByClass( c2 );
        if( ret2 == true )
        {
                cout << "通过成员函数:c1和c2两个立方体相等" << endl;
        }
        else
        {
                cout << "通过成员函数:c1和c2两个立方体不相等" << endl;
        }
}

int main()
{
        test01();
        return 0;
}

 

2. 对象的构造和析构 

对象的初始化清理

  1. 构造函数:没有返回值,没有void,类名相同,可以发生重载,可以有参数
  2. 析构函数:没有返回值,没有void,函数名称:~类名,不可以发生重载,不可以有参数

系统会默认调用 构造函数和析构函数,而且只会调用一次。

如果程序员没有提供构造和析构,系统会默认提供,空实现。

 构造函数的分类:

  • 按照参数进行分类:无参构造函数(默认构造函数)、有参构造函数
  • 按照类型进行分类:普通构造函数、拷贝构造函数
class Person
{
 public: // 构造和析构必须写在pubilc下才可以调用
        
        Person()
        {
            cout << "默认构造函数调用" << endl;
        }

        Person(int a)
        {
            cout << "有参构造函数调用" << endl;
        }

        // 拷贝构造函数
        Person(const Person &p)
        {
            m_Age = p.m_Age;
            cout << "拷贝构造函数调用" << endl;
        }

        ~Person()
        {
            cout << "析构函数调用" <

 

3. 初始化列表

include 
using namespace std;


class Person
{
public:
        // 有参构造函数 初始化数据
        /*Person( int a, int b, int c )
        {
                m_A = a;
                m_B = b;
                m_C = c;
        }*/

        // 利用初始化列表 初始化数据
        // 构造函数后面 :属性(参数),属性(参数)...
        Person(int a, int b, int c):m_A(a),m_B(b),m_C(c)
        {}

        int m_A;
        int m_B;
        int m_C;
};

void test01()
{
        Person p1(10,20,30);
        cout << "p1的m_A:" << p1.m_A << endl;
        cout << "p1的m_B:" << p1.m_B << endl;
        cout << "p1的m_C:" << p1.m_C << endl;
}

int main()
{
        test01();
        return 0;
}

初始化列表语法:

在构造函数后面 :属性(值/参数),属性(值/参数)...

 

4. 类对象作为成员

#include 
using namespace std;

class Phone
{
public:
        Phone()
        {
                cout << "手机的默认构造函数调用" << endl;
        }
        
        Phone(string name)
        {
                m_PhoneName = name;
        }
        
        ~Phone()
        {
                cout << "手机的析构函数调用" << endl;
        }
        
        string m_PhoneName;
};

class Game
{
public:
        Game()
        {
                cout << "Game的默认构造函数调用" << endl;
        }

        Game(string name)
        {
                m_GameName = name;
        }

        ~Game()
        {
                cout << "Game的析构函数调用" << endl;
        }

        string m_GameName;
};

class Person
{
public:
        Person()
        {
                cout << "Person的默认构造函数调用" << endl;
        }

        ~Person()
        {
                cout << "Person的析构函数调用" << endl;
        }

        Person(string name)
        {
                m_Name = name;
        }

        string  m_Name;  // 姓名
        Phone   m_Phone; // 手机
        Game    m_Game;  // 游戏
};

void test01()
{
        Person p;
        p.m_Phone.m_PhoneName = "三星";
        p.m_Game.m_GameName = "斗地主";
}

int main()
{
        test01();
        return 0;
}

C++基础学习笔记 day03_第2张图片

类对象作为类成员时候,构造顺序先将对象一一构造然后再构造自己,析构函数顺序相反。

#include 
using namespace std;

class Phone
{
public:
        Phone()
        {
                cout << "手机的默认构造函数调用" << endl;
        }

        Phone(string name)
        {
                cout << "手机的有参构造函数调用" << endl;
                m_PhoneName = name;
        }

        ~Phone()
        {
                cout << "手机的析构函数调用" << endl;
        }

        string m_PhoneName;
};

class Game
{
public:
        Game()
        {
                cout << "Game的默认构造函数调用" << endl;
        }

        Game(string name)
        {
                cout << "Game的有参构造函数调用" << endl;
                m_GameName = name;
        }

        ~Game()
        {
                cout << "Game的析构函数调用" << endl;
        }

        string m_GameName;
};

class Person
{
public:
        Person()
        {
                cout << "Person的默认构造函数调用" << endl;
        }

        ~Person()
        {
                cout << "Person的析构函数调用" << endl;
        }

        Person(string name, string phoneName, string gameName) : m_Name(name), m_Phone(phoneName), m_Game(gameName)
        {
                cout << "Person的有参构造函数调用" << endl;
                //m_Name = name;
        }

        void playGame()
        {
                cout << m_Name << "玩" << m_Phone.m_PhoneName << "牌的" << m_Game.m_GameName << "游戏" << endl;
        }

        string  m_Name;  // 姓名
        Phone   m_Phone; // 手机
        Game    m_Game;  // 游戏
};

void test01()
{
        Person p("狗蛋","苹果","王者荣耀");
        //p.m_Phone.m_PhoneName = "三星";
        //p.m_Game.m_GameName = "斗地主";
        p.playGame();
}

int main()
{
        test01();
        return 0;
}

C++基础学习笔记 day03_第3张图片

 当类对象作为类的成员时候,构造顺序是先构造类对象的构造,然后构造自己

析构顺序与构造相反

 

4. 对象创建

C语言中malloc:

  1. 程序员必须确定对象的长度;
  2. malloc返回一个void *指针,C++不允许将void *赋值给其他任何指针,必须强转;
  3. malloc可能申请内存失败,所以必须判断返回值来确保内存分配成功
  4. 用户在使用对象之前必须记住对它的初始化,构造函数不能显示调用初始化(构造函数是由编译器调用),用户有可能忘记调用初始化函数。

4.1 new 运算符

C++解决动态内存分配的方案是把创建一个对象所需的操作都结合在一个称为new运算符里。

当用new创建一个对象时,它就在堆里为对象分配内存并调用构造函数完成初始化。

Person * person = new Person;

相当于:

Person *person = (Person *)malloc(sizeof(Person));
if( person == NULL )
{
    return 0;
}
person->Init(); // 构造函数

 

new 运算符和 delete 运算符:

  1. 所有new出来的对象 都会返回该类型的指针
  2. malloc 返回 void * 还要强转
  3. malloc会调用构造吗?不会! new会调用构造
  4. new是运算符,malloc是函数
  5. delete也是运算符,配合new用
  6. new 出来的对象用void * 接收,会释放不了
  7. new 出来的数组,如何释放?delete [] ...
  8. new 出来的数组,肯定会调用默认构造

你可能感兴趣的:(C++)