C++面向对象1:类与对象

目录

1.回顾结构体

2.类

3.成员函数可以放在哪里

4.文件结构

5.#include<>和#include“”

6.类里面的构造函数和析构函数

7.对象数组与对象指针

8.this指针

8.类里面的const和static

const

static


1.回顾结构体

struct Student
{	
    char name[4];
    int born;
    bool male; 
};
struct Student stu;
strcpy(stu.name, "Yu");
stu.born = 2000;
stu.male = true;

缺点:

a)无法检查数据正确与否

b)用指针操作容易越界跑到别的地方去

使用类解决

2.类

class Student
{
  public://访问限定符
    char name[4];
    int born;
    bool male; 
    void setName(const char * s)
    {
        strncpy(name, s, sizeof(name));
    }
    void setBorn(int b)
{ ...
Student yu;//实例化对象
yu.setName("Yu");//让数据操作更加安全

3.成员函数可以放在哪里

class Student
{
  private:
    char name[4];
    int born;
    bool male; 
  public:
    void setName(const char * s)//inline函数
    {
        strncpy(name, s, sizeof(name));
    }
    void setBorn(int b) //inline函数
    {
        born = b;
    }
    void setGender(bool isMale);//只放一个函数声明
    void printInfo();
};
inline void Student::setGender(bool isMale)//在类外定义inline函数是内置函数
{
    male = isMale;
}
void Student::printInfo()//不是inline
{
    cout << "Name: " << name << endl;
    cout << "Born in " << born << endl;
    cout << "Gender: " << (male ? "Male" : "Female") << endl;
}

默认属性(变量)一般定义为私有,方法和行为(函数)定义为公有的

复杂函数写外面

简单函数写里面

4.文件结构

如果程序比较大,写在hpp里面比cpp好,编译时间短

类的声明写在hpp

函数定义在cpp

声明与定义分开

编译器四个阶段,预处理,编译,汇编,链接

在hpp文件中,只声明不定义

空参构造直接给default,没必要定义,但有参的不能有默认参数,不然不能有空参构造

this是本对象

定义文件定义静态区变量(所有对象共享独此一份)

5.#include<>和#include“”

<>:编译器从编译器指定include路径找头文件

“”:从编译器指定的路径找,还会当前cpp目录下面找

6.类里面的构造函数和析构函数

结构体:申请内存(内存里的数据是乱的(没有初始化))

类:申请内存和调用构造函数(对对象里面的数据成员进行初始化)

没有定义构造函数,编译器会自动生成一个构造函数(没有参数,函数体也是空的)

注意:不能在类声明中对数据成员初始化

用户不能调用构造函数(编译器调用)

定义构造函数

class Student
{
  private:
    // ...
  public:
//构造函数(不需要用户来调用它,而是在建立对象时自动执行)
    Student()//函数名和类名完全一样,没有返回值,在public里
    {
        name[0] = 0;//
        born = 0;
        male = false;
    }//可重载,只要参数列表不同(参数个数或者类型不相同)
Student(const char * initName, int initBorn, bool isMale)//带参数的构造函数
//对不同对象赋予不同初值
    {
         setName(initName);
         born = initBorn;
         male = isMale;
    }
};
Student(const char * initName): born(0), male(true)//简化版
//用参数初始化表对数据成员初始化
{
    setName(initName);
}

定义析构函数(函数没有参数,不能被重载,只能有一个)

注:对象先构造的后析构,后构造的先析构

析构函数调用时机:对象被销毁时被调用

析构在堆区开辟的内存

class Student
{
    // ... 
  public:
    Student()
    {
        name = new char[1024]{0};//不释放会导致内存泄漏,程序消耗的内存越来越多
        born = 0;
        male = false;
        cout << "Constructor: Person()" << endl;
    }
    ~Student()//释放内存关闭文件断掉网络或其他操作
    {
        delete [] name;
    }
};

7.对象数组与对象指针

对象数组(对象数组的每一个元素都是同类的对象)

对象指针(对象空间的起始地址就是对象的指针)

Student * class1 = new Student[3]{
        {"Tom", 2000, true},
        {"Bob", 2001, true},
        {"Amy", 2002, false},
};
delete class1;//只会调用第一对象析构函数
delete []class1;//都会调用(推荐使用)

8.this指针

(指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址)

Student yu  = Student{"Yu", 2000, true};//yu(对象)
//Student yu("Yu", 2000, true);
Student amy = Student{"Amy", 2000, false };
yu.setName("yu");
amy.setName("Amy");//两个对象用同一个函数,系统不知道怎么分别引用yu,

 amy中的数据成员

name: "Yu"

born: 2000

male: true

name: "Amy"

born: 2001

male: false

 不知道哪个对象的name

void setName(const char * s)
{
    strncpy(name, s, 1024);
}

void setBorn(int b)
{
    born = b;
}
void setBorn(int b)
{
    this->born = b;//没有歧义可以省略
}
void setBorn(int born)
{
    this->born = born;
}
// this->born(成员变量)
//born(参数变量)

8.类里面的conststatic

const

数据成员不被改变的对象,常对象必须要有初值

#define VALUE 100(c推荐)
const int value = 100;(c++推荐)
const int * p_int;
int const * p_int;
//一样,指针指向的内容不能透过指针修改
int * const p_int;//内容可修改,指针地址不能改,只能指在那
void func(const int *);
void func(const int &); 
//保证数据不变,安全
class Student
{
  private:
    const int BMI = 24;// const变量
    // ...
  public:
    Student()
    {
        BMI = 25;//can it be modified?
        // ...
    }
    int getBorn() const// const函数,放在后面
    {
        //不可修改成员变量
        born++; //Can it be modified?错误
        return born;
    }
};

定义为const的成员函数 不可以修改类的数据成员(只读)
成员函数内使用类的数据成员时,实际上隐式的引入了 this

static

class Student
{
  private:
//静态成员只有一个(不管有多少对象,只有一份数据)
    static size_t student_total; //仅声明//typedef unsigned int size_t;

  public:
    Student()
    {
        student_total++;
    }
    ~Student()
    {
        student_total--;//实时知道这个对象创建了多少次
    }
static size_t getTotal() {return student_total;}
//静态成员函数主要用来访问静态数据成员,而不访问非静态成员
};

// definition it here

//静态数据成员初始化,但只能在类体外初始化

全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。

所以在静态成员在对象创建之前就已经存在了,静态成员与对象无关,属于整个类,构造函数是构造某个具体的对象。

静态区的数据在bss段,bss段进入main函数之前就要初始化

c++规定,类中属性为静态变量时,要在类外首次初始化

 

size_t Student::student_total = 0;

static size_t getTotal() {return student_total;}

//静态函数里不可以修改非静态数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值