【C++】类&对象

C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。

类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员。

class Box
{
    public:
        double length;  //  盒子长
        double breadth; //  盒子宽
        double height;  //  盒子高
};
Box Box1;
Box Box2;
#include <iostream>
using namespace std;
class Box
{
    public:
        double length;
        double width;
        double height;
        // 成员函数声明
        double volume(void);
        void set(double len, double bre, double hei);
};
// 成员函数定义
double Box::volume(void)
{
    return length * width * height;
}
void Box::set(double len, double wid, double hei)
{
    length = len;
    width = wid;
    height = hei;
}
int main()
{
    Box Chengdu;
    Chengdu.length = 4.0;
    Chengdu.width = 6.9;
    Chengdu.height = 4.55;
    cout << Chengdu.volume();
    return 0;   
}

成员函数

  • 把定义和原型写在类定义内部的函数, 是类的一个成员, 可操作类的任意对象, 可访问对象的所有成员
    • 可定义在类内部/范围解析运算符::定义
    • 类定义中定义的成员函数将函数声明为内联的(不用inline标识符
class Box
{
    public:
        double length;
        double width;
        double height;
        double Volume(void)
        {
            return length * breadth * height;
        }
};
        /* 或 */
double Box::Volume(void)
{
    return length * breadth * height;
}
Box box1;   //  创建对象
box1.Volume();  //  调用成员函数

类访问修饰符

  • 数据封装: 防止函数直接访问类类型的内部成员
    • public: 公有成员
    • protected: 受保护成员
    • private: 私有成员

公有成员

  • 公有成员在程序中类的外部可访问, 可不用任何成员函数来设置/获取公有变量值
class line
{
    public:
        double length;
        void setLength(double len);
        double getLength(void);
}

私有成员

  • 私有成员变量/函数在类外部不可访问/查看, 仅有类和友元函数可访问私有成员
class Box
{
    public:
        void setWidth(double wid);
        double getWidth(void);
    private:
        double width;
};
void Box::setWidth(double wid)
{
    width = wid;
}
double Box::getWidth(void)
{
    return width;
}

保护成员

  • 受保护成员类似私有成员, protected成员在派生类(子类)可访问
class Box
{
    protected:
        double width;
};
class SmallBox:Box  //  派生类
{
    public:
        void setSmallWidth(double wid);
        double getSmallwidth(void);
};
void SmallBox::setSmallWidth(double wid)//  子类的成员函数
{
    width = wid;
}
double SmallBox::getSmallwidth(void)
{
    return width;
}

继承

  • 继承: 根据一个类定义另一个类, 简化维护和创建, 重用代码提高效率
    • 基类->派生类
    • 一个类可派生自多个类
      • class class2 : class0,class1
    • 派生类继承所有基类方法
      • 除了: 基类构造函数,析构函数,拷贝构造函数; 重载运算符; 友元函数
class Animal{   //  基类
    rat();
    sleep();
};
class Dog : public Animl(   //  派生类
    bark();
)
  • public继承: 成员访问属性在派生类不变
  • protected继承: 基类public成员访问属性->protected
  • private继承: 基类public,protected成员访问属性->private
    • 如不写什么继承, 默认private继承

#include<iostream>
#include<assert.h>
using namespace std;
class A{
    public:
        int a1 = 1;
    protected:
        int a2 = 2;
    private:
        int a3 = 3;
};
class B : public A{
    public:
        void fun(){
            // public,protected可被派生类访问
            cout << a1 << " " << a2 << endl;
        }
};
class C : protected A{
    public:
        void fun(){
            // public->protected可被派生类访问
            cout << a1 << " " << a2 << endl;
        }
};
class D : private A{
    public:
        void fun(){
            // public->private,protected->private可被派生类访问
            cout << a1 << " " << a2 << endl;
        }
};
int main(){
    B b;
    cout << b.a1 << "-";   //正确
    // cout << b.a2 << endl;   //错误,类外不能访问protected成员
    // cout << b.a3 << endl;   //错误,类外不能访问private成员
    b.fun();
    C c;
    // cout << c.a1 << endl;   //错误, 类外不能访问protected成员
    // cout << c.a2 << endl;   //错误,类外不能访问protected成员
    // cout << c.a3 << endl;   //错误,类外不能访问private成员
    c.fun();
    D d;
    // cout << b.a1 << endl;   //错误,类外不能访问private成员
    // cout << b.a2 << endl;   //错误,类外不能访问private成员
    // cout << b.a3 << endl;   //错误,类外不能访问private成员
    d.fun();
    system("pause");
    return 0;
}

构造&析构函数

构造函数

  • 类的一种特殊的成员函数, 在创建类的新对象时执行
    • 构造函数名称=类名称, 不返回任何类型(包括void)
    • 可用于为某些成员变量设置初始值
#include<iostream>
using namespace std;
class Line
{
    public:
        void setLength(double len);
        double getLength(void);
        Line();
        // Line(double len);   //   带参数的构造函数
    private:
        double length;
};
Line::Line(void)    // 定义成员函数, 包括构造函数
{
    cout << "create" << endl;
    // length = len;
}
void Line::setLength(double len)
{
    length = len;
}
double Line::getLength(void)
{
    return length;
}
int main()
{
    Line line;
    // Line line(10.0);
    line.setLength(78.98);
    cout << line.getLength();
    return 0;
}

初始化列表

Line::Line(double len):length(len)
{}
/* == */
Line::Line(double len)
{
    length = len;
}

析构函数

  • 析构函数是类的一种特殊成员函数, 每次删除创建的对象时执行
    • 与类同名, 不返回不带参数
    • 在跳出程序(关闭文件, 释放内存)前释放资源
#include <iostream>
using namespace std;
class Line
{
    public:
        void setLength(double len);
        double getLength(void);
        Line();
        ~Line();
    private:
        double length;
}

拷贝构造函数

  • 拷贝构造函数: 一种特殊构造函数, 创建对象时在使用同一类中之前创建的对象来初始化新创建对象
    • 使用另一个同类型对象来初始化新创建对象
    • 复制对象作为参数传递给函数
    • 复制对象, 从函数返回该对象
#include<iostream>
using namespace std;
class Line
{
    public:
        int getLength(void);
        Line(int len);      //  构造函数
        Line(const Line &obj);  //  拷贝构造函数
        ~Line();    //  析构函数
    private:
        int *ptr;
};
Line::Line(int len) //  成员函数定义, 包括构造函数
{
    cout << "调用构造函数" << endl;
    ptr = new int;  //  为指针分配内存
    *ptr = len;
}
Line::Line(const Line &obj){
    cout << "调用拷贝构造函数,为ptr分配内存" << endl;
    ptr = new int;
    *ptr = *obj.ptr;
}
Line::~Line(void){
    cout << "释放内存" << endl;
    delete ptr;
}
int Line::getLength(void){
    return *ptr;
}
void display(Line obj){
    cout << obj.getLength() << endl;
}
int main(){
    Line l1(98.77);
    Line l2 = l1;
    display(l1);
    display(l2);
    cout<<"为什么乱码";
    return 0;
}

友元函数

  • 友元函数: 定义在类外部, 有权访问类的所有private成员和protected成员
    • 并非成员函数
    • 友元函数
    • 友元类: 类所有成员都是友元
#include<iostream>
using namespace std;
class Box
{
    double width = 10.89;
public:
    double length = 2.4;
    friend void printWidth(Box box);// 声明友元
};
void printWidth(Box box)    //  不是任何类的成员函数
{
    cout << box.width;
}
int main()
{
    Box box1;
    printWidth(box1);
    return 0;
}

内联函数

  • 内联函数通常与类一起使用, 编译器把函数的代码副本放在每个调用该函数的地方, 对内联函数任何修改需重新编译函数所有客户端
    • inline: 定义内联函数, 若已定义的函数多于一行, 编译器忽略inline限定符
inline int Max(int x, int y)
{
    return (x>y)?x:y;
}

this指针

  • 每一个对象都可通过this指针访问自己的地址
    • this指针是所有成员函数的隐含参数, 成员函数内部可用来指向调用对象
    • 友元函数不是成员, 无this指针
  • 指向类的指针: ->调用
#include<iostream>
using namespace std;
class Box
{
    double length;
    double width;
    double height;
public:
    Box(double len, double wid, double hei)
    {
        length = len;
        width = wid;
        height = hei;
    }
    double Volume()
    {
        return length * width * height;
    }
    double Compare(Box box)
    {
        return this->Volume() > box.Volume();
    }
};
int main()
{
    Box box1(5.6, 4.6, 99.5);
    Box box2(54.4, 40.2, 0.7);
    cout << box1.Compare(box2);
}

静态成员

  • 静态成员: static,无论创建多少个类的对象, 静态成员只有一个副本
    • 在类的所有对象中共享
class Box
{
    double length;
    double width;
    double height;
public:
    static int count;
    Box(double len, double wid, double hei)
    {
        length = len;
        width = wid;
        height = hei;
        count++;    //  每次创建对象+1
    }
};

静态成员函数

  • 静态成员函数: 与类的任何对象独立开
    • 类对象不存在时也可调用
    • 只能访问静态成员数据, 其他静态成员函数, 类外其他函数
    • 不能访问类this指针
    • 可用于判断某些对象是否被创建
class Box
{
    double length;
    double width;
    double height;
public:
    static int count;
    Box(double len, double wid, double hei)
    {
        length = len;
        width = wid;
        height = hei;
        count++;    //  每次创建对象+1
    }
    static int GetCount()
    {
        return count;
    }
};
int Box::count = 0; // 初始化类的静态成员
int main()
{
    Box b1(1,2,3);
    cout << Box::GetCount() ;
    return 0;
}

多态

  • 基类的函数被编译器设置为基类版本, 即静态链接
  • 在函数前放置virtual, 编译器看到了指针内容, 每个子类都有一个area()的独立实现, 即多态(可有多个不同类, 都带同名但不同实现)
  • 虚函数: virtual声明的函数, 派生类中重新定义基类定义的虚函数时, 令编译器不静态链接到该函数, 即动态链接
  • 纯虚函数: 基类中不能对虚函数实现
    • virtual int area() = 0;
class Shape{
    protected:
        int width, height;
    public:
        Shape(int a=0, int b=0)
        {
            width = a;
            height = b;
        }
        virtual int area()
        {
            cout << "parent";
            return 0;
        }
};

猜你喜欢

转载自blog.csdn.net/weixin_46143152/article/details/126762489