一起学习交流~

c/c++细节知识点 14类的构造析构继承

c++面试准备 laomuji 3周前 (09-05) 86次浏览 已收录 0个评论

目录

概念

/*
面向对象三大特征:封装 继承 多态

封装:
把客观事物封装成抽象的类,对不可信的数据和操作进行隐藏

继承:
基类 --> 派生类

多态:
多态以封装和继承为基础
多态分为:
1.重载多态:函数重载、运算符重载(编译期)
2.子类型多态:虚函数(运行期)
3.参数多态:类模板、函数模板(编译器)
4.强制多态:基本类型转换,自定义类型转换(隐式转换属于编译期,显示转换属于运行期)
静态多态(编译期/早绑定):
如函数重载、运算符重载
动态多态(运行期/晚绑定):
基类指针或者引用调用虚函数将发生动态绑定

访问控制、构造函数、析构函数

1.访问控制
public 公开,可以被外部访问
private 私有,仅类内部访问
protected 保护,仅类内部以及派生类访问

2.构造函数
在创建对象时会调用构造函数,无论是直接生成对象 还是使用new 都会调用构造函数

3.默认构造函数
在未定义构造函数的类中,会存在一个默认构造函数,不需要参数
也可以自定义无参构造函数

4.自定义构造函数
构造函数可以有多个,参数必须不同,生成对象时,根据参数决定调用的构造函数

5.析构函数
当对象过期时(被回收,被delete等),会自动调用析构函数

6.继承分为三种
public公有继承:基类的public还是public,protected还是protected,private在派生类中还是无法访问
protected保护继承:基类的public和protected变为protected,private在派生类中还是无法访问
private私有继承:基类的public和protected变为private,private在派生类中还是无法访问
缺省的继承为私有继承

7.继承的构造和析构顺序
构造:基类->派生类
析构:派生类->基类

8.多继承的构造和析构顺序
构造顺序和继承顺序相同,从左往右依次构造
析构顺序和继承顺序相反,从右往左依次析构

9.多继承的同名成员
需要使用范围解析运算符
基类::成员来调用多继承的同名成员

10.显示构造函数和隐式构造函数
如果类存在一个参数的构造函数或除了第一个参数均有默认值时,可以使用=号进行隐式构造
使用explicit关键字可以防止隐式构造

11.在构造函数的声明中使用:对类内部变量进行初始化及对父类构造
class Class14_A {
    int a;
public:
    Class14_A(int num) { a = num; }
};

class Class14_B : public Class14_A{
    int b;
    int c;
public:
    Class14_B(int num1,int num2,int num3):Class14_A(num1) ,c(num3) {
        b = num2;
    }
};
*/

代码

#include<iostream>
using namespace std;
class Class14_1_A {
public:
    int a;
private:
    int b;
protected:
    int c;
};

class Class14_1_B :Class14_1_A {
public:
    void show() {
        cout << a << " " << c << endl;//子类可以访问父类的public和protected
    }
};

int main14_1() {
    Class14_1_A c1;
    c1.a = 123;//在类外部只有public可以被访问
    Class14_1_B c2;
    return 0;
}

class Class14_2_A {
private:
    int a;
    double b;
    char c[50];
public:
    void show() {
        cout << a << " " << b << " " << c << endl;
    }
};
class Class14_2_B {
private:
    int a;
    double b;
    char c[50];
public:
    void show() {
        cout << a << " " << b << " " << c << endl;
    }
    Class14_2_B() {
        a = 0;
        b = 1.1;
        memset(c, 0, sizeof(c));
    }
};

class Class14_2_C {
private:
    int a;
    double b;
    char c[50];
public:
    void show() {
        cout << a << " " << b << " " << c << endl;
    }
    Class14_2_C() {
        a = 0;
        b = 0;
        memset(c, 0, sizeof(c));
    }
    Class14_2_C(int arg1) {
        a = arg1;
        b = 0;
        memset(c, 0, sizeof(c));
    }
    Class14_2_C(int arg1,double arg2) {
        a = arg1;
        b = arg2;
        memset(c, 0, sizeof(c));
    }
    Class14_2_C(int a,double b,const char*c) {
        this->a = a;//同名变量会屏蔽,使用this指针调用类中的a而不是当前函数的a
        this->b = b;
        memcpy(this->c, c, strlen(c) + 1);
    }

};

int main14_2() {
    Class14_2_A a;//没有构造函数会调用默认构造函数,但未对任何类成员变量进行初始化
    a.show();

    Class14_2_B b;//自定义了无参构造函数 会调用无参构造函数
    b.show();

    //定义了不同参数的构造函数会根据参数的不同调用对应的构造函数来生成对象
    Class14_2_C c1;
    Class14_2_C c2(123);
    Class14_2_C c3(123, 123.321);
    Class14_2_C c4(123, 234, "abc");
    c1.show();
    c2.show();
    c3.show();
    c4.show();

    return 0;
}

class Class14_3 {
    int i;
public:
    Class14_3(int i) {
        this->i = i;
        cout << i << " 构造函数被调用" << endl;
    }
    ~Class14_3() {
        cout << i << " 析构函数被调用" << endl;
    }
};
void func14() {
    Class14_3 a(1);
    Class14_3* b = new Class14_3(2);
    delete b;
}
int main14_3() {
    func14();
    Class14_3 c(3);
    Class14_3* d = new Class14_3(4);
    //delete d;//new创建的对象必须使用delete才会自动调用析构函数
    //d->~Class14_3();//虽然手动可以调用析构函数,但是不推荐这么做
    return 0;
}

class Class14_BASE {
public:
    int a;
protected:
    int b;
private:
    int c;
};

//公有继承不改变基类的访问控制
class Class14_Derive1 : public Class14_BASE {
public:
    void show() {
        cout << a;
        cout << b;
        //cout << c;//派生类无法访问基类的私有成员
    }
};
class Class14_Derive1_1 : public Class14_Derive1 {
public:
    void show() {
        cout << a;
        cout << b;
        //cout << c;
    }
};
int main14_4_1() {
    Class14_Derive1 d1;
    Class14_Derive1_1 d2;
    d1.a;
    d2.a;
    return 0;
}

//保护继承只能在派生类中访问基类成员
class Class14_Derive2 : protected Class14_BASE {
public:
    void show() {
        cout << a;
        cout << b;
        //cout << c;
    }
};
//因为被a,b变成了protected 所以可以被派生类访问
class Class14_Derive2_1 : public Class14_Derive2 {
public:
    void show() {
        cout << a;
        cout << b;
        //cout << c;
    }
};
int main14_4_2() {
    Class14_Derive2 d1;
    Class14_Derive2_1 d2;
    //d1.a;
    //d2.a;
    return 0;
}

//私有继承只能在当前类中访问派生类
class Class14_Derive3 : private Class14_BASE {
public:
    void show() {
        cout << a;
        cout << b;
        //cout << c;
    }
};
//因为被a,b变成了private 所以不能被派生类访问
class Class14_Derive3_1 : public Class14_Derive3 {
public:
    void show() {
        //cout << a;
        //cout << b;
        //cout << c;
    }
};
int main14_4_3() {
    Class14_Derive3 d1;
    Class14_Derive3_1 d2;
    //d1.a;
    //d2.a;
    return 0;
}

class Class14_Class_A {
public:
    Class14_Class_A() {cout << "class A create" << endl;}
    ~Class14_Class_A() {cout << "class A delete" << endl;}
};
class Class14_Class_B : Class14_Class_A {
public:
    Class14_Class_B() {cout << "class B create" << endl;}
    ~Class14_Class_B() {cout << "class B delete" << endl;}
};
class Class14_Class_C : Class14_Class_B {
public:
    Class14_Class_C() {cout << "class C create" << endl;}
    ~Class14_Class_C() {cout << "class C delete" << endl;}
};

int main14_5() {
    Class14_Class_C* c = new Class14_Class_C();
    delete c;
    return 0;
}

class Class14_BASE1 {
public:
    int num = 1;
    Class14_BASE1() { cout << "Class14_BASE1 create" << endl; }
    ~Class14_BASE1() { cout << "Class14_BASE1 delete" << endl; }
};

class Class14_BASE2 {
public:
    int num = 2;
    Class14_BASE2() { cout << "Class14_BASE2 create" << endl; }
    ~Class14_BASE2() { cout << "Class14_BASE2 delete" << endl; }
};

class Class14_BASE3 {
public:
    int num = 3;
    Class14_BASE3() { cout << "Class14_BASE3 create" << endl; }
    ~Class14_BASE3() { cout << "Class14_BASE3 delete" << endl; }
};
//多继承时,缺省也是private,用逗号分割
class Class14_Derive : public Class14_BASE1,protected Class14_BASE2,Class14_BASE3 {
public:
    Class14_Derive() { cout << "Class14_Derive create" << endl; }
    ~Class14_Derive() { cout << "Class14_Derive delete" << endl; }
    void show() {
        //cout << num << endl;//多继承时父类的同名变量不能直接使用,会提示变量不明确
        //使用范围解析运算符来调用父类的同名变量或函数
        cout << (Class14_BASE1::num) << endl;
        cout << (Class14_BASE2::num) << endl;
        cout << (Class14_BASE3::num) << endl;
    }
};
int main() {
    Class14_Derive d;
    d.show();
    return 0;
}
喜欢 (1)
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论