继承和深浅拷贝

1.构造函数

作用:批量创建具有相同属性和方法的实例对象

语法:

function 函数名(形参){

this.xxx = xxx

}

let p = new 函数名(实参)

!!!1.函数名的首字母要大写; 2.调用时要使用new关键字;3.不需要返回值; 4.需要在函数体内部通过this关键字接收属性。

new关键字的作用:

1.创建一个空对象

2.将this指向这个空对象

3.执行构造函数内部的代码

4.返回这个新对象

方法过载:直接挂载到构造函数内部的方法,如果实例化了多个对象,就意味着会在内存中开辟多个空间,用来存储具有相同功能的方法,造成内存浪费。

解决方法过载:使用原型对象

2.原型

作用:共享属性和方法

特性:

1.每一个构造函数都会有一个prototype,这就是原型对象,也叫显式原型,挂载到原型对象上的方法可以被共享;

2.每一个实例对象都会有一个__proto__,这就是对象的原型,也叫隐式原型,他会指向构造函数的原型对象

3.每一个原型对象都会有一个constructor,这就是构造器,他会指向构造函数本身。

3.原型链

作用:规定了对象的属性和方法的查找规则。首先在构造函数上查找,找到就执行,并终止查找;没有就在构造函数的原型对象上查找,如果还没有找到就会在Object的原型对象上查找,如果还没找到就会保存

特性:

1.构造函数的原型对象也是一个对象,他也会有隐式原型,会指向Object的原型对象

2.Object的原型对象又是一个对象,他也会有隐式原型,会指向null

3.Object的原型对象也会有一个构造器,他会指向Object这个构造函数本身

原型链图:

4. ES5寄生组合式继承

`步骤`
    1.属性继承
        //原理:强制将父构造函数内部的this指向子构造函数的实例对象
        //方法:在子构造函数内部,通过call方法调用父构造函数,call的第一个参数就是子构造函数的实例对象
        //语法:
        Father.call(this,参数1,参数2)
    2.方法的继承
        //原理:强制将子构造函数原型对象的隐式原型指向父构造函数的原型对象
        //方法:Son.prototype = Object.create(Father.prototype)
        //Object.create():创建一个新对象,该对象的隐式原型指向源对象
        let tep = Object.create(Father.prototype)
        Son.prototype = tep
    3.手动将子构造函数的原型对象的构造器指回子构造函数本身
        //方法:Son.prototype.constructor = Son

5.ES6的类

作用:批量创建具有相同属性和方法的实例对象

语法:

class 类名{
    //构造器函数:挂载属性
    //静态属性可以不用写在构造器函数里面,比如pig
    pig = '猪'
    。constructor(形参){
        this.属性 = 值
    }
    //原型方法
    方法名(){ }
    //静态方法:不可以被实例对象使用,也不可以被继承的方法
    static 方法名(){ }
}
let p = new 类名(实参)

ES6类的继承:

`步骤`:
    1.使用extends关键词实现方法的继承:class 子类 extends 父类{ }
    2.使用super关键词:constructor(){
        //属性的继承
        super(要继承的属性)  
        //先继承再自有
        this.自有属性 = 自有属性  
    }
    
class Father{
    //构造器函数
    constructor(cat,dog){
        this.cat = cat
        this.dog = dog            
    }
}
class Son extends Father{
    constructor(cat,dog,sheep){
        //super():实现 对属性的继承
        super(this,cat,dog)
        this.sheep = sheep    
    }
}
let p1 = new Son('猫','狗','羊')

6.不同数据类型的内存分配

基本数据类型:字符串,数值型,布尔值,null,undefined,Symbol,BigInt(大整型)

引用数据类型:数组,对象,函数

不同数据类型的内存分配:

1.对于基本数据类型,会在栈中开辟一个空间,存放对应的数据;

2.对引用数据类型,会在栈中开辟一个空间,存放该数据的具有唯一性的地址(引用),该地址会指向堆内存里面的真实数据

数据赋值:

1.基本数据类型,如果直接用等号赋值,新旧变量之间互不影响;

2.引用数据类型,如果直接用等号赋值,实际上赋的是地址,不同变量的地址会指向堆内存里的同一条数据,就造成了数据共享的问题:改变一个,另一个也会跟着改变

解决问题:浅拷贝和深拷贝

7.浅拷贝和深拷贝

浅拷贝:

1.对于引用类型的第一层,拷贝的值,而其他层(引用类型嵌套),拷贝的依然是地址

2.语法:Object.assign( { },源对象 ) | { ... 源对象 }

深拷贝:

1.无论拷贝的引用类型数据的层级,拷贝的都是值

2.语法:JSON.parse ( JSON.stringify ( 源对象 ) )

 

### C++ 多态中的拷贝构造函数实现 在 C++ 中,当涉及到多态性继承时,拷贝构造函数的行为可能会变得复杂。这是因为多态通常依赖于指针或引用操作对象,而拷贝构造函数则涉及按值传递对象的情况。 #### 基本概念回顾 1. **多态** 是通过虚函数机制实现的,允许派生的对象通过基型的指针或引用来调用其特定方法[^1]。 2. **拷贝构造函数** 的作用是创建一个新的对象作为现有对象的一个副本。对于具有继承层次结构的来说,如果未显式定义拷贝构造函数,则编译器会自动生成默认版本[^2]。 3. 如果不注意深浅复制问题,在处理含有指针成员变量或者资源管理的情况下容易引发错误[^3]。 #### 问题分析:多态下的拷贝构造函数 假设有一个基 `Base` 一个派生 `Derived` ,两者都支持多态行为: ```cpp class Base { public: virtual ~Base() {} // 虚析构函数确保正确释放内存 virtual void show() const { std::cout << "Base\n"; } protected: int value; }; class Derived : public Base { public: Derived(int v):value(v){} void show() const override { std::cout << "Derived: " << value << "\n"; } }; ``` 当我们尝试使用拷贝构造函数来复制一个多态对象时,默认情况下会发生切片(slicing),这意味着只有基部分会被真正复制下来,丢失掉任何属于派生的数据成员特性。 #### 解决方案——利用克隆模式 (Clone Pattern) 为了避免上述提到的“对象切割”,可以采用一种称为 “克隆”的设计模式。具体做法是在基中提供一个纯虚函数 clone() 返回指向新分配实例的智能指针,并让每个具体的子负责实现自己的clone逻辑: ```cpp #include <memory> using namespace std; // 修改后的基增加了一个虚拟克隆功能 class Base { public: virtual unique_ptr<Base> clone() const = 0; // 纯虚函数强制所有子都要实现此方法 virtual ~Base(){} virtual void show() const {} }; // 对应修改后的派生也需要给出相应的实现细节 class Derived : public Base { private: int data; public: explicit Derived(int d) :data(d){} unique_ptr<Base> clone() const override{ return make_unique<Derived>(*this); } void show() const override{ cout<<"Data from derived:"<<data<<endl; } }; ``` 这样做的好处在于无论何时需要复制某个未知确切型的多态对象时,都可以安全地调用它的clone方法得到完全一致的新实体而不必担心数据遗失的问题。 #### 总结 为了妥善解决C++多态环境下因拷贝构造而导致的信息损失风险,推荐运用克隆技术代替传统的直接赋值方式。这不仅能够有效保护整个继承体系内的完整性,同时也更加契合面向对象编程的核心理念之一—封装性原则。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值