理解Widget::Widget(QWidget *parent) :QWidget(parent)同C++ 基类和派生类的构造函数

1 QT中这段代码如何理解呢

 Widget::Widget(QWidget *parent) :
    QWidget(parent)
 {
 }

2 首先,来看一个例子

#include <iostream>
using namespace std;
class Base
{
public:
    Base() :m_num(0){    // 构造函数让类范围的m_num被初始化. 
        cout << "this is Base()" << endl;
    }
    Base(int val):m_num(val){
        cout << "this is Base(int val)" << endl;
    }
private:
    int m_num;
};

上方代码定义了一个基类Base,并且有两个构造函数,一个是默认构造函数,一个是有一个整型参数的构造函数。

class BaseChild: public Base
{
public:
    BaseChild(){
        cout << "this is BaseChild()" << endl;
    }
    BaseChild(int val): Base(val){
        cout << "this is BaseChild(val)" << endl;
    }
private:
    int m_num;
};

上方代码定义了一个BaseChild类,并继承Base类,同样的,它也定义了两个构造函数,一个默认,一个有整型参数。

int main(int argc, char *argv[])
{
    BaseChild child1;
    BaseChild child2(5);
 
    return 0;
}

main函数实例化了两个子类实例,child1,child2。child1调用默认构造函数。child2调用有整型参数的构造函数。

输出结果:

  • 创建child1时,是先调用了Base的默认构造函数,再调用自己的默认构造函数
  • 创建child2时,是先调用了Base(int)这个构造函数,再调用自己的整型参数构造函数。

 回头看BaseChild的构造函数

BaseChild(int val): Base(val){
        cout << "this is BaseChild(val)" << endl;
    }

初始化列表中的Base(val)正是调用了我们Base基类的有参构造函数,而这样的写法就刚好是我们开头代码中的那段

Widget::Widget(QWidget *parent) :QWidget(parent)

所以可以类比一下:Widget是调用了QWidget下面的构造函数 

3 总结为 C++ 基类和派生类的构造函数

  • 派生类不能继承基类的构造函数;
  • 派生类执行构造函数时,会调用基类的构造函数,一般来说,需要在派生类构造函数中指明基类构造函数,且必须在函数头指明,例如:
#include<iostream>
using namespace std;

//基类People
class People{
protected:
    char *m_name;
    int m_age;
public:
    People(char*, int);
};
People::People(char *name, int age): m_name(name), m_age(age){}

//派生类Student
class Student: public People{
private:
    float m_score;
public:
    Student(char *name, int age, float score);
    void display();
};
//People(name, age)就是调用基类的构造函数
Student::Student(char *name, int age, float score): People(name, age), m_score(score){ }
void Student::display(){
    cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<"。"<<endl;
}

int main(){
    Student stu("小明", 16, 90.5);
    stu.display();

    return 0;
}
  • 如果不指明,派生类的构造函数就会调用基类的默认构造函数(不带参数的构造函数),此时,如果基类没有默认构造函数(不带参数的构造函数),就会发生编译错误。
#include <iostream>
using namespace std;

//基类People
class People{
public:
    People();  //基类默认构造函数, 如果将该行删除,执行派生类构造函数Student::Student(): m_score(0.0){ }时,会发生编译错误
    People(char *name, int age);
protected:
    char *m_name;
    int m_age;
};
People::People(): m_name("xxx"), m_age(0){ }
People::People(char *name, int age): m_name(name), m_age(age){}

//派生类Student
class Student: public People{
public:
    Student();
    Student(char*, int, float);
public:
    void display();
private:
    float m_score;
};
Student::Student(): m_score(0.0){ }  //派生类默认构造函数
Student::Student(char *name, int age, float score): People(name, age), m_score(score){ }
void Student::display(){
    cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<"。"<<endl;
}

int main(){
    Student stu1;
    stu1.display();

    Student stu2("小明", 16, 90.5);
    stu2.display();

    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhanglixin999/article/details/131303912