首页 > 编程语言 >C++对象切片探秘:派生类对象如何被‘切割’?

C++对象切片探秘:派生类对象如何被‘切割’?

时间:2024-03-22 09:04:10浏览次数:27  
标签:示例 对象 派生类 C++ 切片 基类 指针

 

概述:C++中的对象切片指通过将派生类对象赋值给基类对象,导致派生部分被“切掉”,只保留基类部分。这可能发生在值传递、赋值等操作中。对象切片的基础功能示例展示了派生类对象赋值给基类对象时的现象,而高级功能示例则展示了通过基类指针实现派生类对象的访问和多态。

对象切片(Object Slicing)是指通过将派生类对象赋值给基类对象,导致派生类对象的派生部分被“切掉”,只保留基类部分的现象。这通常发生在使用值传递或赋值操作时。

基础功能:

示例源代码:

#include <iostream>
#include <string>

class Base {
public:
    Base(int baseData) : baseData_(baseData) {}
    virtual void Print() const {
        std::cout << "基类数据:" << baseData_ << std::endl;
    }
private:
    int baseData_;
};

class Derived : public Base {
public:
    Derived(int baseData, const std::string& derivedData)
        : Base(baseData), derivedData_(derivedData) {}
    void Print() const override {
        std::cout << "基类数据:" << GetBaseData() << ", 派生类数据:" << derivedData_ << std::endl;
    }
private:
    std::string derivedData_;
};

void DisplayBaseObject(const Base& obj) {
    obj.Print();
}

int main() {
    Derived derivedObject(42, "派生数据");
    
    // 对象切片发生,只保留基类部分
    Base baseObject = derivedObject;
    DisplayBaseObject(baseObject);

    return 0;
}

在这个示例中,Derived 类公有继承自 Base 类,当派生类对象 derivedObject 被赋值给基类对象 baseObject 时,发生了对象切片。虽然 derivedObject 包含派生类的数据成员,但只有基类部分被保留。

高级功能:

示例源代码:

#include <iostream>
#include <memory>

class Base {
public:
    virtual void Print() const {
        std::cout << "基类数据:" << baseData_ << std::endl;
    }
protected:
    int baseData_ = 0;
};

class Derived : public Base {
public:
    void Print() const override {
        std::cout << "基类数据:" << baseData_ << ", 派生类数据:" << derivedData_ << std::endl;
    }
private:
    std::string derivedData_ = "派生数据";
};

int main() {
    std::unique_ptr<Base> basePtr = std::make_unique<Derived>(); // 指向派生类对象的基类指针

    // 通过基类指针调用虚函数,实现多态
    basePtr->Print();

    return 0;
}

在这个示例中,通过使用智能指针 std::unique_ptr,可以实现指向派生类对象的基类指针。通过基类指针调用虚函数 Print,实现了多态性。这也是对象切片的一种应用,通过基类指针可以访问派生类的虚函数。

 

标签:示例,对象,派生类,C++,切片,基类,指针
From: https://www.cnblogs.com/hanbing81868164/p/18088613

相关文章

  • C++序列点解析:确保代码行为可控的关键步骤
     概述:在C++中,序列点是表达式中确保求值顺序的点。其缺失可能导致未定义行为。基础功能示例演示了自增运算符的序列点,而高级功能示例展示了函数调用的序列点,有助于避免不确定行为。在编写代码时遵循序列点规则是确保程序行为可预测的关键。在C++中,序列点是在表达式中保证求值......
  • C++11自定义字面量操作符
    自定义字面量操作符是从C++11标准开始引入的。它允许程序员为特定类型定义自定义的字面量表示法,以提供更加直观和灵活的语法。通过定义自定义字面量操作符,可以让程序更容易阅读和理解,同时提高代码的可读性和表达能力。根据C++标准(C++Standard),对自定义字面量操作符有如下定义:自......
  • C++开发基础——可变参数与可变参数模板
    一,可变参数1.基础概念可变参数在C语言和C++语言编程中都有应用。可变参数的含义是:在函数传参的时候,参数的数量、类型都是可变的,不确定的。在C语言中,应用到可变参数的是可变参数函数和可变参数的宏。在C++语言中,C++11标准提供了两种使用可变参数的方式:1.如果可变参数的参......
  • C++开发基础——智能指针
    一,智能指针1.智能指针简介智能指针是用法和行为类似于指针的类对象。智能指针的底层对原始指针做了一定的封装。智能指针除了像指针一样可以存储变量的地址,还提供了其他功能,比如可以管理动态内存分配,对引用进行计数等。当智能指针所指向的变量离开了作用域或被重置时,智能......
  • AcWing 1230. K倍区间 C++满分题解
    原题链接https://www.acwing.com/problem/content/1232/题目分析求区间和,我们可以通过前缀和来求出。我们规定sum[i]表示第1个元素到第i个元素的和。那么sum[r]-sum[l-1]就是区间[l,r]的和。一维前缀和for(inti=1;i<=n;i++){scanf("%lld",&sum[i]);......
  • 【WPF应用4】WPF界面对象编辑
    简介WPF(WindowsPresentationFoundation)是.NET框架的一部分,它为开发人员提供了一个用于构建桌面应用程序用户界面的强大平台。WPF界面对象编辑是指在WPF应用程序中创建、设计和修改用户界面元素的过程。这些界面对象不仅包括基本的控件如按钮、文本框和标签,还包括更复杂的......
  • JSP内置对象笔记整理
    JSP内置对象《JavaWeb开发从入门到实战》第四章内置对象:在JSP页面中不需要声明和实例化,可以直接在Java程序片和Java表达式部分使用的对象。分类·:与Input/Output有关的内置对象与Context有关的内置对象与Servlet有关的对象与Error有关的内置对象与Input/Output有关的......
  • 限流器(流控)+ 线程 C++实现
    在C++中,你可以使用互斥锁(mutex)和条件变量(conditionvariable)来实现一个简单的限流器(流控)以及线程。下面是一个简单的例子,它创建了一个限流器类,该类允许一定数量的线程同时访问某个资源。#include<iostream>#include<thread>#include<mutex>#include<condition_variable>......
  • C++反射
    反射教程让程序看到自己的数据,并且能够对数据进行操作类型萃取对类型做萃取,有一组混合类型,将特定类型获取出来核心思路:使用模板来匹配查找例子:指针类型萃取解除一层指针,三级变二级,二级变一级template<typenameT>structremove_pointer{};template<typenameT>stru......
  • C++版数据结构与算法
    大家好,今天开始给大家每天带来C++版的数据结构与算法,后面也会包括C#的系统学习。这段代码是一个C++实现的排序算法集合。其中包括选择排序(selectionsort)、冒泡排序(bubblesort)、插入排序(insertionsort)和归并排序(mergesort)。算法后越往后越难,此次做这个系列博客,是想从......