博主头像
小雨淅沥

Some things were meant to be.

OOP课程笔记:第一章 类和对象

第一章 类和对象

1.基本概念

对象是由一组属性(attribute)和一组行为(behavior)构成的。

在C++中,每个对象都是由数据函数(即操作代码)这两部分组成的。

面向对象程序设计中每一组数据都是有特定的用途的,是某种操作的对象。也就是说,一组操作调用一组数据

把相关的数据和操作放在一起,形成一个整体,与外界相对分隔。这就是面向对象的程序设计中的对象


在C++,中对象的类型称为类(class)。类代表了某一批对象的共性和特征。类是对象的抽象,而对象是类的具体实例(instance)

class Student{     
private :            
    char Name[20];
    float Math;
    float Chinese;
public :
    float average;
    void SetName(char *name);
    void SetMath(float math);
    void SetChinese(float ch);
    float GetAverage(void);
};    // 分号注意不要少

2.关键字

关键字成员类型作用域
private私有成员只允许该类内的成员函数使用私有的成员数据
public公有成员可以在类内或类外自由使用
protected保护成员仅允许该类及该类的派生类

3.类的成员

如果未加说明,类中成员默认的访问权限是private,即私有的。

在下示例中,在类外不能直接使用 xy ,必须通过 Setxy()xy 赋值,通过 Print() 输出 xy

class A{ 
    float x, y;
public:
    void Setxy(float a, float b){
        x = a; 
        y = b; 
    }
    void Print(void){ cout << x << ‘\t’ << y << endl;}
};

成员函数与成员数据的定义不分先后,可以先说明函数原型,再在类体外定义函数体。

class A{
    float x, y;
public:
    void Setxy(float a, float b);                // 体内声明函数
    void Print(void);                        
};
void A::Setxy(float a, float b){                // 体外定义
    x = a;
    y = b;
}
void A::Print(void){
    cout << x << '\t' << y << endl;
}

注意两点 :

1.类具有封装性,并且类只是定义了一种结构,所以类中的任何成员数据均不能使用关键字 extern autoregister 限定其存储类型。

2.在定义类时,只是定义了一种导出的数据类型,并不为类分配存储空间,所以,在定义类中的数据成员时,不能对其初始化

class Test { 
    int x = 5,y = 6;     // 是不允许的
    extern float x; // 是不允许的
};

struct 与 class

在C++语言中,结构体类型 struct 只是类 class 的一个特例。

结构体类型与类的唯一的区别在于:在中,其成员的缺省的存取权限是私有的;而在结构体类型中,其成员的缺省的存取权限是公有的。


内联成员函数

当我们定义一个类时,可以在类中直接定义函数体。这时成员函数在编译时是作为内联函数来实现的。
同时,我们也可以在类体外定义类的内联成员函数,在类体内声明函数

在类体外定义时,在成员函数的定义前面加上关键字 inline

class A{
    float x, y;
public:
    void Setxy(float a, float b);            // 声明内联函数
    void Print(void);
};
inline void A::Setxy(float a, float b){        // 定义内联函数
    x = a;
    y = b;
}
inline void A::Print(void){ cout << x << 't' << y << endl;}

4.对象

在定义类时,只是定义了一种数据类型,即说明程序中可能会出现该类型的数据,并不为类分配存储空间

类的变量我们称之为对象对象是类的实例

在建立对象时,只为对象分配用于保存数据成员的内存空间,而成员函数的代码为该类的每一个对象所共享。


对象的使用

一个对象的成员就是该对象的类所定义的成员,有成员数据和成员函数,引用时同结构体变量类似,用 . 运算符。

class A{
    float x, y;
public:
    float m, n;
    void Setxy(float a, float b){
        x = a;
        y = b;
    }
    void Print(void){ cout << x << '\t' << y << endl; }
};
void main(void){
    A a1, a2;             // 定义对象
    a1.m = 10;
    a1.n = 20;          // 为公有成员数据赋值
    a1.Setxy(2.0, 5.0); // 为私有成员数据赋值
    a1.Print();
}

访问私有成员

用成员选择运算符 . 只能访问对象的公有成员,而不能访问对象的私有成员或保护成员

若要访问对象的私有的数据成员,只能通过对象的公有成员函数来获取

class A{
    float x, y;
public:
    float m, n;
    void Setxy(float a, float b){
        x = a;
        y = b;
    }
    void Print(void){ cout << x << '\t' << y << endl; }
};
void main(void)
{
    A a1, a2;
    a1.m = 10;
    a1.n = 20;    // 为公有成员数据赋值
    a1.x = 2;    // 非法,私有成员不可以在类外访问
    a1.y = 5;    // 非法,私有成员不可以在类外访问
    a1.Setxy(2.0, 5.0);
    a1.Print();
}

同类型的对象之间可以整体赋值,这种赋值与对象的成员的访问权限无关。

class A{
    float x, y;
public:
    float m, n;
    void Setxy(float a, float b){
        x = a;
        y = b;
    }
    void Print(void){ cout << x << '\t' << y << endl; }
};
void main(void){
    A a1, a2;
    a1.m = 10;
    a1.n = 20; 
    a1.Setxy(2.0, 5.0);
    a2 = a1;            // 同类型对象赋值,相当于成员数据之间相互赋值
    a1.Print();
    a2.Print();
}

类的作用域

类体的区域称为类作用域。类的成员函数与成员数据,其作用域都是属于类的作用域,仅在该类的范围内有效。

class A{
    float x, y;
public:
    float m, n;
    void Setxy(float a, float b){
        x = a;
        y = b;
    }
    void Print(void) { cout << x << '\t' << y << endl;}
};
void main(void){
    A a1, a2;
    a1.m = 20;
    a1.n = 10;
    a1.Setxy(2.0, 5.0);        // 类的作用域内
    a1.Print();                // 类的作用域内

    Setxy(2.0, 5.0);        // 不允许
    Print();                // 不允许
}

对象的作用域

分为全局对象局部对象局部静态对象等。

class A                        // 文件作用域,整个文件有效
{
    float x, y;
public:
    float m, n;
    void Setxy(float a, float b){
        x = a;
        y = b;
    }
    void Print(void){ 
        cout << x << '\t' << y << endl; 
    }
} a3, a4;
void main(void){
    A a1, a2;
    class B{                // 块作用域,在函数内有效
        int i, j;
    public:
        void Setij(int m, int n){
            i = m;
            j = n;
        }
    };
    B b1, b2;
    a1.Setxy(2.0, 5.0);
    b1.Setij(1, 2);
}

类的嵌套

类B包含在类A中,为嵌套定义。

在类 A 的定义中,并不为 b1 , b2 分配空间,只有在定义类 A 的对象时,才为嵌套类的对象分配空间。嵌套类的作用域在类 A 的定义结束时结束。

class A{
    class B{
        int i, j;
    public:
        void Setij(int m, int n){
            i = m;
            j = n;
        }
    };
    float x, y;
public:
    B b1, b2;    // 嵌套类的对象
    void Setxy(float a, float b){
        x = a;
        y = b;
    }
    void Print(void){
        cout << x << '\t' << y << endl;
    }
};

5.成员函数

成员函数的重载

成员函数可以带有缺省的参数,也可以重载成员函数。
重载时,函数的形参必须在类型或数目上不同。

class Test{
    int x, y;
    int m, n;
public:
    void Setxy(int a, int b){
        x = a;
        y = b;
    }
    void Setxy(int a, int b, int c, int d){
        x = a;
        y = b;
        m = c;
        n = d;
    }
    void Printxy(int x) { cout << “m = "<<m<<'\t'<<“n=" << n << endl; }
    void Printxy(void) { cout << "x=" << x << '\t' << "y=" << y << endl; }
};
void main(void)
{
    Test p1, p2;
    p1.Setxy(3, 5);
    p2.Setxy(10, 20, 30, 40);    // 参数不同
    p1.Printxy();
    p2.Printxy();
    p2.Printxy(2);                // 参数类型不同
}

使用指针引用对象成员函数

class A{
    float x, y;
public:
    float Sum(void) { return x + y; }
    void Set(float a, float b){
        x = a;
        y = b;
    }
    void Print(void) { cout << "x=" << x << '\t' << "y=" << y << endl; }
};
void main(void)
{
    A a1, a2;
    A *p;             // 定义类的指针
    p = &a1;          // 给指针赋值
    p->Set(2.0, 3.0); // 通过指针引用对象的成员函数
    p->Print();
    cout << p->Sum() << endl;
    a2.Set(10.0, 20.0);
    a2.Print();
}

6.this指针

不同对象占据内存中的不同区域,它们所保存的数据各不相同,但对成员数据进行操作的成员函数的程序代码均是一样的。
当对一个对象调用成员函数时,编译程序先将对象的地址赋给 this 指针,然后调用成员函数,每次成员函数存取数据成员时,也隐含使用this指针。

this 指针具有如下形式的缺省说明,实际上是一个常量指针

class classname{};
classname *const this; // this实际上是一个常量指针

以一个字符串的类作为示例代码

class S{
public:
    char *strp;
    int length;
    void Ini(char *s);
    void Print(void);
    void Copy(S &s);
};
void S::Copy(S &s){
    if (&s == this)            // this 指针和传入的待复制的类进行比较
        cout << "不能复制本身\n ";
    else{
        if (strp)
            delete[] strp;
        length = s.length;
        strp = new char[length + 1];
        strcpy(strp, s.strp);
    }
}
OOP课程笔记:第一章 类和对象
https://www.rainerseventeen.cn/index.php/Code-Basic/12.html
本文作者 Rainer
发布时间 2025-10-18
许可协议 CC BY-NC-SA 4.0

评论已关闭