07-内存管理、命名空间和继承

2021-07-21  本文已影响0人  一亩三分甜

《C++文章汇总》
上一篇介绍了引用和汇编《06-封装、内存布局、堆、构造和析构》,本文介绍内存管理、命名空间和继承。

1.内存管理:自己创建的自己释放,自己惹的祸,自己承担

struct Car {
    int price;
    Car(){
        cout << "Car::Car()" << endl;
    }
    ~Car(){
        cout << "Car::~Car()" << endl;
    }
};
struct Person {
    int m_age;
    Car *car;
    //用来做初始化的工作
    Person(){
        m_age = 0;
        car = new Car;
        cout << "Person::Person()" << endl;
    }
    //用来做内存清理的工作
    ~Person(){
        delete car;
        cout << "Person::~Person()" << endl;
    }
};
int main(){
    //内存泄露:该释放的内存没有得到释放
    {
        Person person;
    }
    getchar();
    return 0;
}
//输出
Car::Car()
Person::Person()
Car::~Car()
Person::~Person()
image
图片.png
image
图片.png

2.声明和实现分离

//Person.hpp文件
class Person {
private:
    int m_age;
public:
    void setAge(int age);
    int getAge();
    Person();
    ~Person();
};

//Person.cpp文件
#include "Person.hpp"
void Person::setAge(int age){
    m_age = age;
}
int Person::getAge(){
    return m_age;
}
Person::Person(){
    m_age = 0;
}
Person::~Person(){
    
};

调用
#include "Person.hpp"
int main(){
    Person person;
    person.setAge(10);
    cout << "age is " << person.getAge() << endl;
    getchar();
    return 0;
}
//输出
age is 10

3.命名空间:命名空间可以用来避免命名冲突

3.1 命名空间的基本用法

class Person{
    int m_age;
};

namespace Cloud {
     int m_age;
     void func(){
         cout << "Cloud::func" << endl;
     };
     class Person{
         int m_age;
         int m_name;
     };
}
int main(){
    Cloud::m_age = 10;
    Cloud::func();
//    Cloud::Person person;
//    cout << sizeof(person) << endl;
    getchar();
    return 0;
}
//输出
Cloud::func

二义性:不同命名空间相同名字函数


image

外部和命名空间同时有相同名字函数func,要调用func,此时存在全局默认的命名空间,没有名字,要调用函数用::
有个默认的全局命名空间,我们创建的命名空间默认都嵌套在它里面


图片.png
class Person{
    int m_age;
};

namespace Cloud {
     int m_age;
     void func(){
         cout << "Cloud::func" << endl;
     };
     class Person{
         int m_age;
         int m_name;
     };
}

void func(){
    cout << "func()" << endl;
}

namespace Fish {
     int m_age;
     void func(){
         cout << "Fish::func()" << endl;
     };
}
int main(){
    using namespace Cloud;
    using namespace Fish;
//    m_age = 1;//二义性,Cloud和Fish里面均有m_age
    Fish::func();
    ::func();
    ::Cloud::func();
//    Cloud::m_age = 10;
//    Cloud::func();
    
//    Cloud::Person person;
//    cout << sizeof(person) << endl;
    getchar();
    return 0;
}
//输出
Fish::func()
func()
Cloud::func

3.2 命名空间的合并

以下两种写法是等价的

namespace ManKind {
   int m_name;
}
namespace ManKind {
   int m_sex;
}
合并
namespace ManKind {
   int m_name;
   int m_age;
}

.h和.cpp文件中的命名空间

namespace A {
  class Person{
    int m_age;
    int m_name;
    Person();
    ~Person();
  };
}
namespace A {
   Person::Person(){};
   Person::~Person(){};
}

3.3 其他编程语言的命名空间

◼ Java
Package
◼ Objective-C
类前缀

4.继承

4.1继承的基本特性

◼ 继承,可以让子类拥有父类的所有成员(变量\函数)
◼ 关系描述
◼ Student是子类(subclass,派生类) ◼ Person是父类(superclass,超类)
◼ C++中没有像Java、Objective-C的基类 Java:java.lang.Object Objective-C:NSObject

struct Person {
    int m_age;
    void run(){};
};
struct Student:Person{
    int m_score;
    void study(){};
};

struct Worker:Person{
    int m_salary;
    void work(){};
};

int main(){
    return 0;
}

4.2 继承的成员变量在内存布局

◼ 父类的成员变量在前,子类的成员变量在后


image

5.成员访问权限

◼ 成员访问权限、继承方式有3种
public:公共的,任何地方都可以访问(struct默认)
protected:子类内部、当前类内部可以访问
private:私有的,只有当前类内部可以访问(class默认)

struct Person {
public:
    int m_age;
};
struct Student:private Person{
    
};
struct GoodStudent:Student{
    void work(){
        m_age = 10;//会报错,因为Person是私有继承,无法在子类中直接访问m_age
    }
};

◼ 子类内部访问父类成员的权限,是以下2项中权限最小的那个
成员本身的访问权限
上一级父类的继承方式

◼ 开发中用的最多的继承方式是public,这样能保留父类原来的成员访问权限
◼ 访问权限不影响对象的内存布局

struct Person {
private:
    int m_age;
public:
    void setAge(int age){
        m_age = age;
    }
    int getAge(){
        return m_age;
    }
};
struct Student:public Person{
    
};
struct GoodStudent:Student{
    void work(){
        setAge(10);
        getAge();
    }
};

通过class定义一个类,继承的默认方式为private
通过struct定义一个类,继承的默认方式为public

上一篇 下一篇

猜你喜欢

热点阅读