C++ 学习笔记03

一、访问权限


public: 公有权限 程序的任何位置都可以使用
protected: 受保护的,派生类和类的内部使用。什么叫派生类?等讲完继承才能用。
private: 私有的,只有类的内部可以使用。
类的内部:类的成员函数。

类的内部 派生类 全局
public
protected ×
private × ×

访问权限定义的越小越好

示例1

#include <iostream>
using namespace std;
class Person
{
private://私有权限
    int money;//私有
    int house;;//私有
    int phone;;//私有
public://公有权限
    void setInfo(int m, int h, int p) //公有
    {
        money = m;  
        house = h;
        phone = p;
    }
    void show()//公有
    {
        cout<<money<<" "<<house<<" "<<phone<<endl;
    }
};
int main()
{
    Person p;
p.money = 10;//语法错误,因为main函数不是
    //Person类的成员函数,所以不能使用Person类的私有成员
    p.setInfo(5,6,7);
    p.show();
}

练习1

定义类Array 向数组中输入整数 并求出数组元素中的最大值,最小值和平均值

  1. 数组成员变量private修饰
    int * p;
    int length;
  2. 成员函数input(int length);
    length为数组的长度;
    数组动态创建new(按照输入的长度,创建数组)
    功能:cin方式,输入数组的值
  3. 成员函数 int max(); 要求带返回值
  4. 成员函数 int min();
  5. 成员函数 int avg();

查看练习代码

#include <iostream>
using namespace std;
class Array
{
private:
    int* p;
    int length;
public:
    void input(int l)
    {
        length = l;
        p = new int[length];
        for(int i = 0;i < length;i++)
        {   
            cout<<"请输入一个整数"<<endl;
            cin>>p[i];
        }
    }
    int max()
    {
        int m = p[0];
        for(int i = 1;i < length;i++)
        {
            if(p[i] > m)
            {
                m = p[i];
            }
        }
        return m;
    }
    int min()
    {
        int m = p[0];
        for(int i = 1;i < length;i++)
        {
            if(p[i] < m)
            {
                m = p[i];
            }
        }
        return m;
    }
    int avg()
    {
        int sum = 0;
        for(int i = 0;i < length;i++)
        {
            sum += p[i];
        }
        return sum/length;
    }
};
int main()//main输出函数的返回值
{
    Array a;
    a.input(5);
    cout<<a.max()<<endl;
    cout<<a.min()<<endl;
    cout<<a.avg()<<endl;
    return 0;
}

二、封装性

封装的概念

成员变量:在程序设计中不是每个属性都需要对外公开(女人不公开体重跟年龄,男人不公开身高及收入),
而有一些类的属性是对外公开的(名字、性别等);
因此在设计类时必须在类的表示法中定义属性和行为的公开级别,将不对外公开的属性使用private进行修饰。
但因为被private修饰,所以外部无法对其进行写入与读取的操作。
所以我们可以在public下留出读(getXXX())或写(setXXX())的操作函数;

示例2

#include <iostream>
#include <string>
using namespace std;
class Person{
private://类中的成员成员变量,如果没有特殊需要,不可以写成public
        int money;
        int id ;
public:
        string name;
public:
        void init(string n,int m,int i){
            name = n;
            money = m;
            id = i;
        }

        int getMoney(){ 
            return money;
        }
//使用函数对成员变量读写,可以把成员变量的值控制在允许的范围内。
//如果直接把成员变量写成public的,则没有办法去控制它的值。
//setXXX 和getXXX只是命名的习惯,这种命名方式不是语法的要求。
        void setMoney(int m)
        {
if(m < money)
return;
            money = m;
        }

        void setId(int i){

            id = i;
        }
        int getId(){
            return id;
        }

};
int main()
{
    Person p;
    p.init("zhangsan",10000,1);
    cout << p.getId() << "." << p.name << " have " <<p.getMoney() << " dollars " <<endl ;
    return 0;
}

封装:

  1. 将具有相同属性和行为的一系列对象封装成一个类,将一系列重复性的代码封装成函数;
  2. 数据的隐藏,将不对外公开的属性和行为使用private进行修饰,保证数据安全。

练习2

创建一个类Product,成员变量name,price,使用set和get进行赋值与获取,在主函数创建三个产品对象并赋值,打印.

查看练习代码

#include <iostream>
using namespace std;
class Product
{
private:
    string name;
    int price;
public:
    void setName(string n)
    {
        name = n;
    }

    string getName()
    {
        return name;
    }

    void setPrice(int p)
    {
        price = p;
    }

    int getPrice()
    {
        return price;
    }
};

int main()
{
    Product p1;
    p1.setName("手抓饼");
    p1.setPrice(6);

    Product p2;
    p2.setName("烤冷面");
    p2.setPrice(7);

    Product p3;
    p3.setName("麻辣烫");
    p3.setPrice(20);

    cout<<p1.getName()<<" "<<p1.getPrice()<<endl;
    cout<<p2.getName()<<" "<<p2.getPrice()<<endl;
    cout<<p3.getName()<<" "<<p3.getPrice()<<endl;

    return 0;
}

三、分文件定义类

示例3

在类外部实现成员函数

#include <iostream>
using namespace std;
class Person
{
private:
    int age;
public:
    void setAge(int a);//类的内部只做函数的声明
    void show();
};

void Person::setAge(int a)//Person:: 告诉编译器,这是Person类中的成员函数
{
    age = a;
}

void Person::show()
{
    cout<<age<<endl;
}

int main()
{
    Person* p = new Person;
    p->setAge(18);
    p->show();
}

示例4

分.h和.cpp

main.cpp
#include <iostream>
#include "person.h"
int main()
{
    Person* p = new Person;
    p->setAge(18);
    p->show();
}
person.h
#ifndef PERSON_H
#define PERSON_H
class Person
{
private:
    int age;
public:
    void setAge(int a);
    void show();
};
#endif
person.cpp
#include "person.h"
#include <iostream>
using namespace std;
void Person::setAge(int a)
{
    age = a;
}
void Person::show()
{
    cout<<age<<endl;
}

练习3

定义一个类Cube ,数据成员:length,width,height (分文件)
成员函数如下功能:
1.由键盘输入长方体的长宽高input();
2.计算长方体体积int volume();
3.输出长方体体积show();
建议文件的名字和类的名字保持一致。
Cube.h Cube.cpp main.cpp

查看练习代码

Cube.h
#ifndef _CUBE_H_
#define _CUBE_H_
class Cube
{
private:
    int length;
    int width;
    int height;
public:
    void input();
    int volume();
    void show();
};
#endif
Cube.cpp
#include "Cube.h"
#include <iostream>

using namespace std;

void Cube::input()
{
    cin>>length>>width>>height;
}

int Cube::volume()
{
    return length*width*height;
}

void Cube::show()
{
    cout<<volume()<<endl;
}
main.cpp
#include "Cube.h"
#include <iostream>

using namespace std;

void Cube::input()
{
    cin>>length>>width>>height;
}

int Cube::volume()
{
    return length*width*height;
}

void Cube::show()
{
    cout<<volume()<<endl;
}

四、构造函数

1.构造函数的作用和语法

在创建对象的时候会自动调用的函数,是c++中特殊成员函数。
主要作用是在创建对象时初始化对象,为对象的成员变量赋值
对象的初始化:参考如下代码

class Tank
{
private:
        int m_iposX;
        int m_iposY;
public:
void init()
{
    m_iposX = 0;
    m_iposY = 0;
}
};
int main()
{
    Tank t1;  
    t1.init(); 
    Tank t2;
    t2.init();
    return 0;
}

对象的初始化: 有且仅初始化一次,根据条件初始化
思考:
如何能避免误操作呢
初始化函数 如何避免误操作
忘记调用初始化函数
重复调用初始化操作

2.构造函数的规则和特点

创建语法如下:

  1. 名字必须与类同名 无返回值 可能有参数
  2. 访问权限一般是public,一旦私有构造函数,那么在类的外部将不能创建对象。
  3. 用户不能调用构造函数 只有在类对象创建时 自动调用
  4. 实例化对象时,只用到一个构造函数

示例5

无参构造函数
#include<iostream>
using namespace std;
class Person
{
private:
    string name;
    int age;
public:
    Person()//构造函数
    {
        cout<<"i am constructor...."<<endl;
    }
    void show()
    {
        cout<<"我是"<<name<<"  今年"<<age<<endl;
    }
};
int main()
{
    Person x;//创建对象的时候,自动调用构造函数
    Person b;
}

示例6

无参构造函数 成员变量赋值
#include<iostream>
using namespace std;
class Person
{
private:
    string name;
    int age;
public:
    Person()
    {
        name="guanyu";//在构造函数中给成员变量赋值
        age = 0;
    }
    void show()
    {
        cout<<"我是"<<name<<"  今年"<<age<<endl;
    }
};
int main()
{
    Person x;
    x.show();
}

示例7

有参构造函数
class Person 
{
    public:
        Person()
        {
            age = 10;
            cout<<"无参构造函数"<<endl;
        }
        Person(int a)//重载一个有参的构造函数
        {
            age = a;
            cout<<"create a...."<<endl;
        }
        void show()
        {
            cout<<age<<endl;
        }
private:
    int age;
};
int main()
{
    Person x;  //执行无参构造
    x.show();
    Person p1(20);//创建对象时,给构造函数传入实参列表。  执行有参构造
    p1.show();
Person* p2 = new Person(40);//执行有参构造
p2->show();
}

3.默认构造函数

显示---->隐式
1)默认构造函数,当没有显式的定义构造函数时,系统会自动生成一个默认构造函数,
2)没有参数也没有逻辑;仅仅为了有构造函数而存在。
3)一旦显式的定义了构造函数,将不会生成默认构造函数

示例8

#include <iostream>
using namespace std;
class Person
{
private:
    int age;
public:
    Person(int a)//因为在这里显示的定义了一个构造函数,所以现在
        //整个类中只有一个构造函数,所以创建对象的时候必须给实参列表
    {
        age = a;
    }
    //如果这里不显示的定义构造函数,会有一个默认构造函数,没有参数没有逻辑
    //所以创建对象的时候不能有参数
};
int main()
{
    Person p(1);
    return 0;
}

练习4

计算长方形周长 构造函数实现长宽赋值(构造函数带参数) 分文件写!show()函数输出周长的值

查看练习代码

Rect.h
#ifndef _RECT_H_
#define _RECT_H_
class Rect
{
private:
    int width;
    int height;
public:
    Rect(int w, int h);
    void show();
};
#endif
Rect.cpp
#include "Rect.h"
#include <iostream>
using namespace std;
Rect::Rect(int w, int h)
{
    width = w;
    height = h;
}
void Rect::show()
{
    cout<<2*(width+height)<<endl;
}
main.cpp
#include "Rect.h"
int main()
{
    Rect r1(1,2);//给构造函数传参数,注意不是直接调用构造
    r1.show();
    Rect* r2 = new Rect(3,4);
    r2->show();
    delete r2;
    return 0;
}

4.构造函数的初始化列表

构造函数用冒号形式引出初始化列表
格式:成员变量名(初始值)
注意: 初始化成员列表的顺序应该和成员声明的顺序保持一致,不建议使用成员初始化其他成员
成员的初始化顺序,是按照声明的顺序进行,和初始化列表的顺序没有关系。

示例9

#include <iostream>
using namespace std;
class Rect
{
private:
    int width;
    int height;
public:
    Rect(int w, int h):width(w),height(h)//初始化列表,用w初始化成员width,用h初始化成员height,初始化列表只能初始化成员变量  ()可以是构造函数的参数,也可以是常量
    {
    }
    int perimeter()
    {
        return width*2+height*2;
    }
};
int main()
{
    Rect* p = new Rect(10, 20);
    cout<<p->perimeter()<<endl;
    Rect r(10, 20);
    cout<<r.perimeter()<<endl;
}
End

本文标题:C++ 学习笔记03

本文链接:http://chisato.cn/index.php/archives/105/

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

声明:转载请注明文章来源。

最后修改:2021 年 10 月 08 日 03 : 43 PM
如果觉得我的文章对你有用,请随意赞赏