QT学习之C++面向对象基础

QT学习之C++面向对象基础

1. 类和对象

1.1 类的定义

C++中的类可以简单看作是结构体的升级版,但是在类中成员不仅可以是变量也可以是函数。变量可以称作类的属性,函数可以称为类的方法

示例:

class stduent
{
  public:
    int id;//成员之1
    int age;//成员之2
    void test(void);//成员之3,函数

  private:
    int score;//成员之4
};

创建的方法类似结构体的定义方法,关键字 public 确定了类的成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。也可以指定类的成员为 privateprotected,表明成员只能在类的内部进行访问。

1.2 创建对象

对象是类的实例化,使用对象可以访问类的成员,创建方法有两种。

可以使用下面方法直接创建:

//类名 对象名
student stdent1;//创建一个student类的对象student1

或者使用new方法在堆中创建:

student *student1 = new student;

使用这种方法创建的对象,可以使用delete方法删除,删除后就可以释放堆中的内存。如:

delete student1;

1.3 类的成员函数

成员函数也是类的成员,可以在类中直接定义,也可以在类中声明,在外部定义。

在类中定义:

    class student
    {
      public:
        int id;//成员之1
        int age;//成员之2
        void test(void){//成员函数
            printf("internal class\n");
        }

      private:
        int score;//成员之3
    };

在外部定义时,需要使用范围解析运算符 :: 表明函数所属的类,格式如下:

返回值 类名::函数名(参数)
    class student
    {
      public:
        int id;//成员之1
        int age;//成员之2
        void test(void);//声明成员函数

      private:
        int score;//成员之3
    };

    void student::test(void)//成员函数定义
    {
        printf("external class\n");
    }

1.4 访问类的成员

使用对象可以在外部访问类的public成员,使用普通方法创建的对象使用(.)访问,使用指针new创建的对象则使用(->)访问,与C语言中的结构体成员访问方法类似。

注意:默认无修饰符的类成员是private或者protected的。

#include <iostream>

using namespace std;

class student
{
  public:
    int id;//成员之1
    int age;//成员之2
    void test(void);

  private:
    int score;//成员之3
};

//成员函数
void student::test(void)
{
    printf("class function!\n");

}

int main()
{
    student student1;
    student *student2 = new student;
    //访问类的成员变量
    student1.id = 20;
    student2->id = 21;
    //访问类的成员函数
    student1.test();
    student2->test();

    cout << "student1.id = " << student1.id << endl;
    cout << "student2->id = " << student2->id << endl;
    cout << "Hello World!" << endl;
    return 0;
}
image-20200728180010890

2. 特殊的函数

2.1 重载函数

在一个类中,可以定义同名但函数参数不相同的成员函数,当外部调用时,会自动根据调用函数时传递的参数,来选择对应的函数进行调用。这些函数就是重载函数,C++的这种特性称做重载特性。

在student类中定义三个同名的test函数,每个函数的参数均不相同,调用时传递不同参数调用不同函数。

#include <iostream>

using namespace std;

class student
{
  public:
    int id;//成员之1
    int age;//成员之2
    void test(char Chinese[]);
    void test(int Math);
    void test(float Physic);

  private:
    int score;//成员之3
};


void student::test(char Chinese[])
{
    cout << "Get Chinese Score!" << endl;
}
void student::test(int Math)
{
    cout << "Get Math Score!" << endl;
}
void student::test(float Physic)
{
    cout << "Get Physic Score!" << endl;
}

int main()
{
    student student1;
    char c[] = "Chinese";
    student1.test(c);
    student1.test(100);
    float n=100.0;
    student1.test(n);

    cout << "Hello World!" << endl;
    return 0;
}

运行结果:
image-20200728192415582

2.2 构造函数

构造函数是类的一个特殊成员函数,当使用类创建一个对象时,就会执行这个类的构造函数。

构造函数的名字与类的名字完全一致,构造函数可以带参数,但无返回值。

无参数的构造函数:

class student
{
  public:
    int id;//成员之1
    int age;//成员之2
    void SetScore(int Setscore);//成员函数
    int  GetScore(void);//成员函数
         student();//构造函数
  private:
    int score;//成员之3
};

//构造函数,名字需要与类相同
student::student(){
    cout << "student Object is created!" << endl;
}

主函数:

int main()
{
    student student1;//创建对象时会调用构造函数

    cout << "Hello World!" << endl;
    return 0;
}

结果:
image-20200728182719103

带参数的构造函数:

默认的构造函数没有参数, 需要时可以给构造函数设置参数,传递给类的成员进行初始化操作。需要才创建对象时,传递参数,格式如下:

类名 对象名(参数列表);

如下通过构造函数对类的私有成员score进行赋值操作:

#include <iostream>

using namespace std;

class student
{
  public:
    int id;//成员之1
    int age;//成员之2
    void SetScore(int Setscore);//成员函数
    int  GetScore(void);//成员函数
         student(int Score);//构造函数
  private:
    int score;//成员之3
};

//构造函数
student::student(int Score){
    cout << "student Object is created!" << endl;
    score = Score;
}

//函数功能:设置成绩score
void student::SetScore(int Setscore)
{
    score = Setscore;
}

//函数功能:获取成绩score
int student::GetScore(void)
{
    return score;
}

int main()
{
    student student1(100);//创建对象时,使用构造函数传递参数score的值为100
    cout << "Init score = " << student1.GetScore() << endl;//打印score
    student1.SetScore(99);//重新设置score的值
    cout << "Set score = " << student1.GetScore() << endl;//打印score

    cout << "Hello World!" << endl;
    return 0;
}

输出结果:
image-20200728185726306

2.3 析构函数

析构函数与构造函数相反,当类的对象被删除时执行,同样没有返回值,但是与构造函数不同,析构函数不可以带参数

析构函数的名字也与类的名字相同,但是需要在函数名前加~符号

析构函数可以在跳出程序(比如关闭文件、释放内存等)前进行释放资源等操作。

主函数中使用类创建对象时会调用构造函数,程序运行结束对象被删除时会调用析构函数:

#include <iostream>

using namespace std;

class student
{
  public:
    int id;//成员之1
    int age;//成员之2

    student(int Score);//构造函数
    ~student(void);//析构函数
  private:
    int score;//成员之3
};

//构造函数
student::student(int Score){
    cout << "student Object is created!" << endl;
    score = Score;
}

student::~student(void)
{
    cout << "student Object is deleted!" << endl;
}


int main()
{
    student student1(100);

    cout << "Hello World!" << endl;
    return 0;
}

运行结果:

image-20200728194353467

3. 类的继承

面向对象中继承是一个非常重要的部分。类的继承就是在一个旧的类基础上定义一个新的类,这个新类称为子类,旧类称为父类。子类可以拥有父类部分或全部的属性和方法,这就是继承。新生成的子类可以在父类的基础上修改父类的成员,可以添加更多的属性、方法,可以大大开发提高效率。

继承格式:

class 子类: 继承类型(public/private/protected) 父类

继承类型:类的成员有publicprivateprotected三种类型,继承时可以选择将父类的publicprotected成员(private成员不可继承)继承为子类的publicprivateprotected成员。所以有三种继承类型:

  • 公有继承(public):当一个子类派生自父类的public时,子类的publicprotected成员与父类相同。
  • 保护继承(protected): 当一个子类派生自父类的protected时,子类的publicprotected成员将成为子类的protected成员。
  • 私有继承(private):当一个子类派生自父类的private时,子类的publicprotected成员将成为子类的private成员。

定义一个Animal动物类,再定义一个Dog类(公有继承自Animal类),Dog的对象可以获得Animal的public和protected成员。

子类Dog可以修改父类Animal的已有成员name、Eat(),同时继承了父类的Drink()成员,添加了Bark()。

#include <iostream>

using namespace std;

//animal类
class Animal
{
    public:
        char *name="--->I am an animal<---";
        void Eat(void);//成员函数(技能1):吃
        void Drink(void);//成员函数(技能2):喝

    private:
        void AniamlPrint(void);
};

//吃
void Animal::Eat(void)
{
    cout << "I can eat.." << endl;
}

//喝
void Animal::Drink(void)
{
    cout << "I can drink.." << endl;
}

//Dog类继承自Animal类public部分,公有继承
class Dog: public Animal
{
    public:
        char *name="--->I am a dog<---";
        void Eat(void){
            cout << "I can eat!" << endl;
        }
        void Bark(void);//吠,Dog的成员

};

//吠
void Dog::Bark(void)
{
    cout << "I can bark.." << endl;
}

int main()
{
    Animal animalA;
    Dog WangWang;

    cout << animalA.name << endl;
    animalA.Eat();
    animalA.Drink();

    cout << WangWang.name << endl;
    WangWang.Eat();
    WangWang.Drink();
    WangWang.Bark();

    return 0;
}

运行结果:

虚函数

虚函数也是类的成员函数,需要在函数名前加上virtual关键字声明为虚函数。

定义虚函数的目的:为了允许用父类的指针来调用子类的这个函数

可以用下面这个例子进行说明:

//来自菜鸟教程
#include <iostream>

using namespace std;

class A{
public:
    virtual void foo()
    {
        std::cout << "A::foo() is called" << endl;
    }
};


class B: public A
{
public:
    void foo()
    {
        std::cout << "B::foo() is called" << endl;
    }
};

int main(int argc, char *argv[]) {
    A *a = new B();
    a->foo();
    return 0;
}

*A a = new B();这条语句的意思是创建一个A类型的指针,指向B类的对象。根据指针的指向关系,使用a访问foo()函数自然会调用B类的foo(),因为a指向的是B的对象。这样就实现了使用父类(类型为A)的指针访问子类(B)的函数

结果:

image-20200729181122889

纯虚函数

纯虚函数同样使用virtual关键字进行修饰,但纯虚函数只在父类中进行声明,没有函数的定义(功能实现)。当其他的子类继承这个父类时,都必须实现这个纯虚函数。

定义纯虚函数的目的:实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。

#include <iostream>

using namespace std;

class A{
public:
    virtual void foo()=0;//纯虚函数,只有声明,无定义
};


class B: public A//B继承自A
{
public:
    void foo()//子类B中进行纯虚函数的定义
    {
        std::cout << "foo() is Pure virtual function!" << endl;
    }
};

int main() {
    B b;
    b.foo();
    return 0;
}

结果:
image-20200729182233669

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个简单的结合QtC++面向对象的航班订票系统的示例代码: flight.h ```cpp #ifndef FLIGHT_H #define FLIGHT_H #include <QString> class Flight { public: Flight(QString flightNumber, QString departureCity, QString arrivalCity, int availableSeats); QString getFlightNumber(); QString getDepartureCity(); QString getArrivalCity(); int getAvailableSeats(); void reserveSeat(); void releaseSeat(); private: QString m_flightNumber; QString m_departureCity; QString m_arrivalCity; int m_availableSeats; }; #endif // FLIGHT_H ``` flight.cpp ```cpp #include "flight.h" Flight::Flight(QString flightNumber, QString departureCity, QString arrivalCity, int availableSeats) : m_flightNumber(flightNumber), m_departureCity(departureCity), m_arrivalCity(arrivalCity), m_availableSeats(availableSeats) { } QString Flight::getFlightNumber() { return m_flightNumber; } QString Flight::getDepartureCity() { return m_departureCity; } QString Flight::getArrivalCity() { return m_arrivalCity; } int Flight::getAvailableSeats() { return m_availableSeats; } void Flight::reserveSeat() { if (m_availableSeats > 0) { m_availableSeats--; } } void Flight::releaseSeat() { m_availableSeats++; } ``` mainwindow.h ```cpp #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QListWidgetItem> #include "flight.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_flightListWidget_itemClicked(QListWidgetItem *item); void on_reserveButton_clicked(); void on_releaseButton_clicked(); private: Ui::MainWindow *ui; QList<Flight*> m_flights; Flight* m_selectedFlight; }; #endif // MAINWINDOW_H ``` mainwindow.cpp ```cpp #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // Create some sample flights m_flights.append(new Flight("ABC123", "New York", "Los Angeles", 50)); m_flights.append(new Flight("DEF456", "Chicago", "Houston", 75)); m_flights.append(new Flight("GHI789", "San Francisco", "Seattle", 100)); // Populate the flight list widget foreach (Flight* flight, m_flights) { ui->flightListWidget->addItem(flight->getFlightNumber()); } } MainWindow::~MainWindow() { delete ui; // Delete the flights foreach (Flight* flight, m_flights) { delete flight; } } void MainWindow::on_flightListWidget_itemClicked(QListWidgetItem *item) { // Get the selected flight QString flightNumber = item->text(); foreach (Flight* flight, m_flights) { if (flight->getFlightNumber() == flightNumber) { m_selectedFlight = flight; break; } } // Update the available seats label ui->availableSeatsLabel->setText(QString::number(m_selectedFlight->getAvailableSeats())); } void MainWindow::on_reserveButton_clicked() { // Reserve a seat for the selected flight m_selectedFlight->reserveSeat(); // Update the available seats label ui->availableSeatsLabel->setText(QString::number(m_selectedFlight->getAvailableSeats())); } void MainWindow::on_releaseButton_clicked() { // Release a seat for the selected flight m_selectedFlight->releaseSeat(); // Update the available seats label ui->availableSeatsLabel->setText(QString::number(m_selectedFlight->getAvailableSeats())); } ``` 这个示例代码演示了如何用Qt实现一个简单的航班订票系统,其中使用了C++面向对象编程的一些基本概念,例如类和对象、构造函数和析构函数、公有和私有成员函数、以及访问控制等。在这个示例代码中,Flight类表示一个航班,包含航班号、出发城市、到达城市和可用座位数等信息,同时提供了订票和释放座位等方法。MainWindow类表示主窗口,包含一个航班列表部件、一个选择航班的标签、一个显示可用座位数的标签、一个订票按钮和一个释放座位按钮等控件,同时也负责管理航班列表和处理用户的交互操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值