C++的三大特性及构造函数和析构函数

1) C++ 中类的三大特性是什么?请简要解释。

类的对象:属性(成员变量)行为(成员方法/函数)

类的定义:

class 类名{

权限:

成员变量,

成员方法,

};

三大特性:继承性封装性多态性

继承性 继承允许一个类继承另一个类的属性和方法

继承允许创建一个新的类(派生类或子类)从一个已有的类(基类或父类)派生出来。派生类继承

了基类的所有非 private(私有)成员变量和成员函数(构造函数和析构函数除外),并且可以添

加自己的新成员或者重写基类的成员函数。这就好比子女会继承父母的一些特征,同时也有自己的

个性。

例如下面这个基类Vehicle,它有成员变量speed和成员函数drive(),然后有一个派生类Car继承自

Vehicle,Car类就自动拥有了speed变量和drive()函数避免了代码的重复编写,通过重写drive方

法,所以会输出 “汽车可以驾驶”,而不是Vehicle类中drive函数的车辆可以驾驶。

class Vehicle {
public:
    int speed;
    void drive()
    {
        cout << "车辆可以驾驶" << endl;
    }
};
class Car :public Vehicle {
public:
    void drive()
    {
        cout << "汽车可以驾驶" << endl;
    }
};
int main()
{
    Car car;
    car.speed = 75;
    car.drive();//汽车可以驾驶
    return 0;
}

封装性 将数据和操作封装在类中(将属性和行为看作一个整体,表现事物)),通过访问修饰符控制

访问权限   

常见的访问修饰符有:

public://公有权限:可以类内(成员方法)访问,子类访问,对象访问(通过.访问)

protected://受保护权限:可以类内(成员方法)访问,子类访问

private://私有权限:只能类内(成员方法)访问

例如下面这个银行账户类, 它是由属性(账户余额)和行为(存款,取款)构成了独立的单元,来体现

银行账户这个事物

class BankAccount {
private:
	int balance;//账户余额
public:
	void deposit()
	{
		cout << "存款" << endl;
	}
	void withdraw()
	{
		cout << "取款" << endl;
	}
};
int main()
{
	BankAccount account;
	//account.balance = 5000;//报错:不能修改私有成员变量的值,保证了数据的安全性
	account.deposit();//public成员函数可以在外部访问

}

多态性 多态是通过基类指针或引用调用派生类的函数实现不同的行为

多态主要通过虚函数来实现。当有一个基类指针或引用指向派生类对象时,通过这个指针或引用调

用虚函数,实际调用的是派生类中重写后的虚函数,这是在运行时根据对象的实际类型来决定的

#include <iostream>
using namespace std;
class Animal {
public:
    virtual void makeSound() {
        cout << "Animal makes a sound." << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        cout << "Dog barks." << endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        cout << "Cat meows." << endl;
    }
};
int main()
{
    Dog dog;
    dog.makeSound();//Dog barks.
    return 0;
}

2)什么是构造函数和析构函数?它们的作用是什么?

构造函数:

作用:1.构造函数是给成员变量赋值

对象角度:初始化类对象 ;成员变量角度:对成员变量赋值

定义:2.构造函数和类名相同,没有返回值,不写void

类名()

{

    函数体

}

3.构造函数在创建对象时,编译器自动帮我们调用无需手动调用

4.如果没有实现构造函数,编译器会提供默认的构造函数,不过函数体为空

类名()

{

}

5.构造函数有参数,可以进行重载或者给参数默认值

6.如果我们实现了有参构造,编译器就不会提供默认的无参构造

7.构造函数可以是私有的,但是是在单例模式下。

调用构造函数的三种方式:1.括号法 2.显示法 3.隐式转换法

class point{
    int* p;
public:
    point()
    {
        cout << "调用无参构造函数" << endl;
    }
    point(int n)
    {
        cout << "调用有参数的构造函数" << endl;
        if (n > 0)
        {
            p = new int(10);
        }
        else
        {
            p = NULL;
            cout << "数据不准确" << endl;
        }
    }
    void print()
    {
        if (p) cout <<"打印p指向堆区内存的值" <<* p << endl;
    }
};
int main()
{
    point p1;//调用无参构造
    p1.print();//输出"调用无参构造函数"
    point p2(-3);//输出 "调用有参数的构造函数","数据不准确" 
    p2.print();
    point t(1); //括号法
    point t1 = point(3);//显示法
    point t2 = 3;//隐式转换法
    point t3();//不是括号法调用无参构造,会被编译器识别为函数的声明
    return 0;
}

析构函数

析构函数的主要功能:释放指针变量指向的堆区内存

定义:

定义:~类名()

{

     函数体

}

1.无参数,不能重载

2.没有返回值,不用写void

3.程序销毁对象时自动调用,不用手动调用,且只调用一次

4.名字和类名相同且前面有~

5.没有实现析构函数时,编译器提供默认的析构函数

6.析构函数是释放指针成员变量所指向的堆区内存

7.类外声明,类内实现。

class A {
    int* p;
public:
    A() {
        p = NULL;
    }
    A(int n) {
        p = new int[n];
    }
    ~A(){
        if (p) delete []p;
    }
};
int main()
{
        A* a = new A(3);//先在堆区申请A类型的对象,给构造函数传参参数为3,a在栈区,栈区a指向堆区1的对象,堆区中有指针成员变量p,p指向一块堆区2内存
        //new:先调用malloc开辟堆区内存1,再走构造函数给开辟的这块堆区内存1赋值,
        delete a;//先调用析构函数p释放堆区内存2,在调用free释放堆区内存1
        cout << "well" << endl;
        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值