当前位置: 首页 > article >正文

c++柔性数组、友元、类模版

目录

1、柔性数组: 

 2、友元函数:

3、静态成员 

注意事项

面试题:c/c++ static的作用?

C语言:

C++:

为什么可以创建出 objx

4、对象与对象之间的关系

5、类模版


1、柔性数组: 

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>using namespace std;class MyString
{
private:struct  StrNode{int refcount; //引用计数int slen;int capa;char data[0]; //数组不填或填0就成为柔性数组};private:StrNode* pstr;static const size_t DAFAUSIZE = 32;static const size_t INCSIZE = 2;static StrNode* GetMem(rsize_t n){size_t total = (n > DAFAUSIZE) ? n + 1 : DAFAUSIZE;StrNode* s = (StrNode*)malloc(sizeof(StrNode) + sizeof(char) * total);memset(s, 0, sizeof(StrNode) + sizeof(char) * total);s->capa = total - 1;return s;}static void  FreeMem(StrNode *p){free(p);}
public:MyString(const char* p = nullptr) :pstr(nullptr){if (p != nullptr){int len = strlen(p);pstr = GetMem(len);pstr->refcount = 1;pstr->slen = len;strcpy(pstr->data, p);}}MyString(const MyString &st) :pstr(st.pstr)  //st给当前对象{if (pstr != nullptr){pstr->refcount += 1; //+1 说明有两个对象持有这块空间}}MyString(MyString &&st) :pstr(st.pstr)  //移动构造{st.pstr = nullptr;}~MyString() {if (pstr != nullptr && --pstr->refcount == 0){FreeMem(pstr);}pstr = nullptr;}ostream& operator<<(ostream& out)const{if (pstr != nullptr){out << pstr->data;}return out;}
};
ostream &operator<<(ostream &out, const MyString &st)
{return st << out;
}int main()
{MyString s1 = "chengxi";MyString s2(s1);MyString s3(s2);MyString s4(s3);cout << s3 << endl;return 0;
}

 2、友元函数:

(1)不具有传递特性、继承特性、是单向的。

(2)友元函数分为:函数友元、成员函数友元、类友元

(3)友元函数是访问类的对象非公有属性。

成员函数友元:

using namespace std;
class Base;
class Test
{
private:int sum;
public:Test(int x = 0) :sum(x) {}void SetSum(int x = 0){sum = x;}int GetSum()const { return sum; }int Add(const Base &it);
};class Base
{friend int Test::Add(const Base& it);//成员函数友元int num;
public:Base(int x = 0) :num(x){}
};
int Test::Add(const Base& it)
{return this->sum + it.num;
}int main()
{Test t1(100);Base b1(2);t1.Add(b1);
}

类友元: 

using namespace std;
//Test对象访问base的私有和公有,注意方向
class Base
{friend class Test; 
private:int num;
public:Base(int x = 0) :num(x){}
};class Test
{
private:int sum;
public:Test(int x = 0) :sum(x) {}void SetSum(int x = 0){	sum = x;}int GetSum()const { return sum; }int Add(const Base &it) {return it.num + 10;}int func(const Base& it){return it.num;}
};int main()
{Test t1;Base b1;t1.Add(b1);t1.func(b1);return 0;
}

3、静态成员 

(1) 类静态成员只能在类外进行初始化,

(2)静态成员变量在数据区存储。静态量不属于对象,是被所有对象共享,不管有多少个对象,静态成员只有一份存在于数据区。

(3)静态数据可以在普通方法中使用

(4)为什么不能在参数列表中对静态成员初始化?

答:参数列表,在定义对象的时候要调用构造函数,拿参数列表对数据成员进行创建,静态成员被所有对象共享,在定义不同的对象时都要对静态成员进行构建,c++中,数据成员(对象、变量)在生存期内只能被构建一次。放在参数列表中,被构建了n次,不允许。要在类外进行初始化。

静态成员在类模版中,数据类型不同 ,就会产生不同的 “静态成员”

using namespace std;template<class T>
class Object
{
private:int value;
protected:static int num;
public:Object(int x=0):value(x){}~Object(){}
};class Test :public Object<Test>
{
public:Test(){cout << "Create Test::" << (num += 1) << endl;}
};class Base :public Object<Base>
{
public:Base() {cout << "Create Base:" << (num += 1) << endl;}
};
template<class T>
int Object<T>::num = 0;
int main() {Test t1[1];Base b1[2];return 0;
}

  • Test t1[1];:创建一个包含 1 个 Test 对象的数组,在创建 Test 对象时,会调用 Test 类的构造函数,输出相应的信息。
  • Base b1[2];:创建一个包含 2 个 Base 对象的数组,在创建 Base 对象时,会调用 Base 类的构造函数,输出相应的信息。

注意事项

由于 Object 类的静态成员变量 num 是模板化的,Object<Test> 和 Object<Base> 是不同的模板实例化,它们各自拥有独立的 num 副本。所以在创建 Test 和 Base 对象时,它们的 num 计数是相互独立的。

面试题

C语言:

(1)静态关键字修饰全局/局部变量,存在于数据区,当函数消亡时,静态变量还存在,可以&。

全局变量有static和无的区别?

(2)全局静态变量只在本文件中可见,同一工程的其他文件不可见, (私有),未用static修饰的全局变量,可以用extern在其他文件用。

(3)static修饰函数,此函数只在当前文件夹有效,在其他文件中不能用,(私有)。修饰函数本身而不是修饰返回值 static int* add() {} ,。

C++:
(1)static可以修饰类的成员,要在类外进行初始化。所有的对象都共享同一个静态成员变量,派生的类也共享(但前提是将其设置成protected /public)。

(2)静态成员变量不属于对象,无this,在常方法中可以修改静态成员变量的值,this不修饰它。

static可以修饰属性的类型,要在类外进行初始化,如果是静态常性变量可以在类内进行初始化,但必须要求是整型类型。

(3)static修饰成员方法,static void func(){}  无this指针。静态成员方法无this。

(3)static修饰的成员方法可以访问静态属性也可以访问非静态属性(非静态属性必须把对象传进来)。

静态成员方法可以通过 对象访问,也可以通过类名。

静态成员变量
  • 类的所有对象共享:静态成员变量属于类本身,而不是类的某个对象。无论创建多少个类的对象,静态成员变量都只有一份副本,被所有对象共享。
  • 需要在类外初始化:静态成员变量必须在类外进行初始化,因为它不依赖于对象的创建。

     :obja可以创建出来,指针:4字节

    #include<stdio.h>
    #include<iostream>
    using namespace std;
    class Object
    {
    private:int value;
    private:static Object objx;
    private:Object(int x = 0) :value(x) {cout << "create Obj" << this << endl;}~Object(){cout << "destroy obj:" << this << endl;}
    };
    Object Object::objx(1);int main()
    {return 0;
    }

    • 成员变量
      • int value;:一个私有成员变量,用于存储对象的值。
      • static Object objx;:一个私有静态成员变量,类型为 Object 类本身。静态成员变量属于类,而不是类的某个对象,所有该类的对象共享同一个静态成员变量。
    • 静态成员变量初始化
      • Object Object::objx(1);
        

        这行代码对 Object 类的静态成员变量 objx 进行初始化,调用了 Object 类的构造函数,并将参数 1 传递给构造函数,将 value 成员变量初始化为 1

        为什么可以创建出 objx

        虽然 Object 类的构造函数和析构函数都是私有的,通常情况下,外部代码无法直接创建 Object 类的对象。但是,静态成员变量 objx 是类的一部分,类的内部可以访问其私有成员。因此,在类的外部对静态成员变量 objx 进行初始化时,实际上是在类的作用域内调用了构造函数,这是被允许的。

         

        当程序开始执行时,在进入 main 函数之前,会先对静态成员变量进行初始化,所以 Object::objx 会被创建,调用构造函数输出创建信息。当程序结束时,静态对象 objx 会被销毁,调用析构函数输出销毁信息。

    using namespace std;
    class Object
    {
    private:int value;
    private:static Object objx;
    private:Object(int x = 0) :value(x) {cout << "create Obj" << this << endl;}~Object(){cout << "destroy obj:" << this << endl;}
    public:void Print()const { cout << "value" << value << endl; }void SetValue(int x) { value = x; }int GetValue()const { return value; }//通过静态方法将静态对象的地址返回static Object* getObject(){return &objx;}
    };
    Object Object::objx(1);int main()
    {Object* pa = Object::getObject();Object* pb = Object::getObject();if (pa == pb) { cout << "pa,pb pinter:object" << endl; }pa->Print();pa->SetValue(100);pa->GetValue();pa->Print();return 0;
    }
    • if (pa == pb) { cout << "pa,pb pinter:object" << endl; }:比较 pa 和 pb 的值,如果相等,说明它们指向同一个对象,输出相应信息。由于 objx 是静态对象,无论调用多少次 getObject() 函数,返回的都是同一个对象的地址,所以 pa 和 pb 相等。
    • 通过静态成员函数可以在类外部访问私有静态成员对象,并且由于静态成员对象只有一个实例,无论通过多少个指针访问,操作的都是同一个对象。

    4、对象与对象之间的关系

    依赖关系:用-------> 表示

    一个对象在运行期间会用到另一个对象的关系,通常在运行期间产生,并且伴随运行时的变化依赖关系也发生变化。主要表现为 :“使用关系”。

    关联关系:用——> 表示:

    静态关系,如:学生和学校,是关联关系

    在设计中。关联关系主要体现在目标类型的指针或引用。

    聚合、继承、组合等。

    5、类模版

    template<类型模版参数表>

    类模板不是类,因此无法直接实例化对象,需要在声明类时给定确定的数据类型,编译器才会以此分配内存。对于普通类而言,类的声明和类成员函数的定义可以写在不同的文件中,但是对于类模板来说,最好定义在同一个文件中。

    //define _N 10
    template<class T,int N>
    class SeqStack
    {T* data;int capa;int top;static const int stackinitsize = 100;static const int incsize = 2;static T* GetMen(size_t sz){T* newdata = (T*)malloc(sizeof(T) * sz);if (nullptr == newdata){cout << "malloc fail" << endl;exit(1);}memset(newdata, 0, sizeof(T) * sz);return newdata;}static void FreeMem(T* p){free(p);}public:SeqStack(int sz = stackinitsize) :data(nullptr), capa(sz), top(-1){//data = (T*)malloc(sizeof(T) * capa); //只申请空间不构建对象data = GetMen(capa);}~SeqStack(){}int size()const { return top + 1; }bool empty()const { return size() == 0; }int capacity()const { return capa; }bool full()const { return size() == capacity(); }bool push(const T& x){if (full())return false; //满了调增容函数 top += 1;new(&data[top]) T(x);   //data[++top] = x;构建对象return true;}bool gettop(T *val) {if (empty())return false;val = data[top];return true;}bool poptop(T& val){if (empty())return false;val = data[top];(&data[top])->~T(); //析构top中的对象top -= 1;return true;}bool pop(){if (empty())return false;(&data[top])->T();top -= -1;return true;}};
    int main()
    {SeqStack<int, 10> istack;   //using T:int N:10}
    int main() {ClassName<int> intObj(10);  // 实例化类模板,创建一个处理 int 类型的类对象int result = intObj.getData();std::cout << "Result: " << result << std::endl;ClassName<double> doubleObj(3.14);  // 实例化类模板,创建一个处理 double 类型的类对象double dResult = doubleObj.getData();std::cout << "Result: " << dResult << std::endl;return 0;
    }

    相关文章:

    c++柔性数组、友元、类模版

    目录 1、柔性数组&#xff1a; 2、友元函数&#xff1a; 3、静态成员 注意事项 面试题&#xff1a;c/c static的作用? C语言&#xff1a; C: 为什么可以创建出 objx 4、对象与对象之间的关系 5、类模版 1、柔性数组&#xff1a; #define _CRT_SECURE_NO_WARNINGS #…...

    win10 快速搭建 lnmp+swoole 环境 ,部署laravel6 与 swoole框架laravel-s项目1

    参考文献 1.dnmp环境 https://github.com/yeszao/dnmp 2.laravel6.0文档 https://learnku.com/docs/laravel/6.x 3.laravels 文档 https://github.com/hhxsv5/laravel-s/blob/master/README-CN.md 安装前准备 1.确认已经安装且配置好docker&#xff0c;能在cmd 中运行 docker …...

    【Kafka基础】基础概念解析与消息队列对比

    1 Kafka 是什么&#xff1f; Kafka是一个 分布式流处理平台&#xff0c;主要用于 高吞吐量、低延迟的实时数据流处理&#xff0c;最初由LinkedIn开发。 核心特点&#xff1a; 高吞吐量&#xff1a;支持每秒百万级消息处理持久化存储&#xff1a;消息可持久化到磁盘&#xff0c;…...

    vue将组件中template转为js

    在 Vue 中&#xff0c;组件的 template 需要被转换为 JavaScript 渲染函数&#xff08;Render Function&#xff09;才能在浏览器中运行。Vue 2 和 Vue 3 的转换机制有所不同&#xff0c;主要体现在编译时机、编译工具和输出结果上。 1. Vue 2 的 Template 转换 转换方式 Vue…...

    Centos 8 安装教程(新手版)

    1.需要在阿里开源镜像站下载对应的镜像&#xff0c;如下&#xff1a;https://mirrors.aliyun.com/centos/8.5.2111/isos/x86_64/ 2.打开VM虚拟机&#xff0c;创建新的虚拟机&#xff0c;选择自定义 如图所示点击进行&#xff1a; 选择下载好的镜像 选择“Linux”&#xff0c;版…...

    Vue2函数式组件实战:手写可调用的动态组件,适用于toast轻提示、tip提示、dialog弹窗等

    Vue2函数式组件实战&#xff1a;手写可调用的动态组件 一、需求场景分析 在开发中常遇到需要动态调用的组件场景&#xff1a; 全局弹窗提示即时消息通知动态表单验证需要脱离当前DOM树的悬浮组件 传统组件调用方式的痛点&#xff1a;必须预先写入模板&#xff0c;可能还要用…...

    ESLint语法报错

    ESLint语法报错 运行报错 You may use special comments to disable some warnings. Use // eslint-disable-next-line to ignore the next line. Use /* eslint-disable */ to ignore all warnings in a file.解决方案 关闭eslint的语法检测&#xff0c;在eslintrc.js文件中…...

    大象如何学会太空漫步?美的:科技领先、To B和全球化

    中国企业正处在转型的十字路口。一边是全新的技术、全新的市场机遇&#xff1b;一边是转型要面临的沉重负累和巨大投入&#xff0c;无数中国制造、中国品牌仍在寻路&#xff0c;而有的人已经走至半途。 近日&#xff0c;美的集团交出了一份十分亮眼的2024年财报。数据显示&…...

    Leetcode 3500. Minimum Cost to Divide Array Into Subarrays

    Leetcode 3500. Minimum Cost to Divide Array Into Subarrays 1. 解题思路2. 代码实现 题目链接&#xff1a;3500. Minimum Cost to Divide Array Into Subarrays 1. 解题思路 这一题非常惭愧&#xff0c;没有自己搞定&#xff0c;基本是抄的大佬们的代码&#xff0c;甚至抄…...

    已经使用中的clickhouse更改数据目录

    在更换的目录操作&#xff0c;这里更换的目录为home目录&#xff0c;原先安装的目录在/soft/clickhouse/ ,在该目录下有data目录和log目录 更改前目录 更改后目录 1、停止clickhouse服务 sudo systemctl stop clickhouse-server 2、在home目录创建clickhouse目录,在clickho…...

    PHP的相关配置和优化

    进入etc下面 去掉注释 pid run/php-fpm.pid #指定pid文件存放位置 生成一下子配置文件 这些都是生成的fastcgi的配置文件 进入php中&#xff0c;然后复制模版&#xff0c;生成配置文件 然后编辑文件更改时区 改完之后可以生成启动脚本 这时候刷新之后&#xff0c;再启动会报…...

    体重秤PCBA电路方案组成结构

    体重秤PCBA电路主要由以下几个部分组成&#xff1a; 主控芯片电路 芯片选择&#xff1a;通常采用低功耗、高性能的单片机作为主控芯片&#xff0c;如前面提到的SIC8833等。这类芯片具备丰富的外设接口&#xff0c;可方便地与其他模块进行通信和控制。 电路连接&#xff1a;主控…...

    android 加载本地.svg资源的几种引入方式

    在 Android 中&#xff0c;可以在 XML 布局文件中引入本地 .svg 资源&#xff0c;但需要先转换为 Android 可识别的格式。主要有以下几种方式&#xff1a; 方式 1&#xff1a;使用 Vector Asset&#xff08;官方推荐&#xff09; Android 不支持直接加载 .svg&#xff0c;但可…...

    fio磁盘测试工具使用笔记

    本文介绍磁盘性能测试工具fio在某国产操作系统&#xff08;内核4.19&#xff0c;gcc为7.3.0&#xff09;上的编译和使用。 背景 某项目使用物理机安装某数据库&#xff0c;相关人员提到磁盘性能方面的要求&#xff0c;用fio测试32k的随机读写&#xff0c;性能要达到1万 IOPS。…...

    JavaScrip——BOM编程

    一、BOM核心对象与导航控制 1. location对象&#xff1a;页面跳转与刷新 // 跳转到指定URL location.href "https://example.com"; // 刷新当前页面 location.reload(); // 示例&#xff1a;点击按钮跳转 document.querySelector("#btn").onclick () &…...

    机器学习 分类算法

    【实验名称】 实验&#xff1a;分类算法 【实验目的】 1.了解分类算法理论基础 2.平台实现算法 3. 编程实现分类算法 【实验原理】 分类(Categorization or Classification)就是按照某种标准给对象贴标签(label),再根据标签来区分归类。 【实验环境】 OS&#xff1a;Ubuntu16.0…...

    【leetcode100】每日温度

    1、题目描述 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例 1: 输…...

    <贪心算法>

    前言&#xff1a;在主包还没有接触算法的时候&#xff0c;就常听人提起“贪心”&#xff0c;当时是layman&#xff0c;根本不知道说的是什么&#xff0c;以为很难呢&#xff0c;但去了解一下&#xff0c;发现也不过如此嘛&#xff08;bushi)&#xff0c;还以为是什么高级东西呢…...

    基于银河麒麟桌面服务器操作系统的 DeepSeek本地化部署方法【详细自用版】

    一、3种方式使用DeepSeek 1.本地部署 服务器操作系统环境进行,具体流程如下(桌面环境步骤相同): 本例所使用银河麒麟高级服务器操作系统版本信息: (1)安装ollama 方式一:按照ollama官网的下载指南,执行如下命令: curl -fsSL https://ollama.com/install.sh | sh方…...

    「2025最新版React+Ant Design+Router+TailwindCss全栈攻略:从零到实战,打造高颜值企业级应用

    一站式掌握最新技术栈&#xff01;手把手教你配置路由、集成UI组件库、高效开发秘籍大公开 ReactAntrouteraxiosmocktailwind css等组合安装使用教程 官网&#xff1a;React Native 中文网 使用React来编写原生应用的框架 一&#xff0c;安装 npx create-react-app my-app …...

    Ubuntu 24.04.2 LTS 系统安装python,创建虚拟环境

    在 Ubuntu 24.04.2 LTS 系统中&#xff0c;系统本身自带了 Python 3&#xff0c;不过你还是可以按照下面的步骤来安装和配置 Python 环境。 1. 检查系统自带的 Python 版本 在终端中输入以下命令查看系统自带的 Python 版本&#xff1a; python3 --version如果显示了 Python…...

    redis7.0搭建redis-cluster集群部署实战

    环境 基于3台centos服务 host节点1端口节点2端口master70007001slave170007001slave270007001 安装redis&#xff0c;以及环境准备 安装可以参考https://blog.csdn.net/tao1992/article/details/132614567 安装路径设置了/usr/local/redis 分别在3台服务器上执行 #配置文…...

    CMake学习--如何在CMake中编译静态库、动态库并在主程序中调用

    目录 一、背景知识二、使用方法&#xff08;一&#xff09;编译静态库&#xff08;二&#xff09;编译动态库&#xff08;三&#xff09;在主程序中调用库 三、总结 一、背景知识 在C/C开发中&#xff0c;库&#xff08;Library&#xff09;是预先编译好的代码集合&#xff0c…...

    安美数字酒店宽带运营系统存在SQL注入漏洞

    免责声明&#xff1a;本号提供的网络安全信息仅供参考&#xff0c;不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权&#xff0c;请及时与我联系&#xff0c;我将尽快处理并删除相关内容。 漏洞描述 安美数字酒店宽带运营系统的lang…...

    中级:Git面试题全攻略

    一、引言 在现代软件开发中&#xff0c;Git作为分布式版本控制系统&#xff0c;被广泛应用于代码管理与团队协作。面试官通过Git相关问题&#xff0c;考察候选人对版本控制的基本概念、操作流程以及解决实际问题的能力。本文将深入解读Git的基本操作、分支管理、冲突解决等常见…...

    ubuntu18 server版花屏问题

    新搞了一台dellT150的塔式服务器&#xff0c;装的ubuntu18 server版。 开机后遇到花屏&#xff0c;或者卡在开机界面的问题&#xff0c;和售后技术沟通这个情况是ubuntu自带的显卡驱动包兼容问题。需要做如下设置&#xff1a; 解决&#xff1a; 1.开机&#xff0c;连续按下e…...

    基于神经网络的肾脏疾病预测模型

    构建一个基于神经网络的肾脏疾病预测模型 1. 数据预处理 ​加载数据&#xff1a;读取 kidney_disease.csv 文件&#xff0c;加载患者医疗数据。​删除冗余特征&#xff1a;移除与预测目标无关的列&#xff08;如 al, su 等&#xff09;&#xff0c;保留关键特征&#xff08;如…...

    Oracle常用高可用方案(10)——RAC

    10.2. RAC 10.2.1. 概念 RAC,Real Application Cluster的缩写,业界就称为RAC。RAC最早出现于2001年发布的Oracle 9i版本,之前的版本中,也有类似的产品或技术,叫做OPS,即Oracle Parallel Server的缩写。基于多方面的因素,Oracle 9i之前的类似产品或技术并没有得到广泛应…...

    JavaScript基础-移动端常用开发插件

    在移动Web开发中&#xff0c;为了提升开发效率和用户体验&#xff0c;开发者通常会依赖于一些成熟的JavaScript插件。这些插件封装了复杂的功能&#xff0c;使得实现常见的交互效果变得更加简单快捷。本文将介绍几款广泛使用的移动端开发插件&#xff0c;并通过具体的示例展示它…...

    I/O多路复用 + Reactor和Proactor + 一致性哈希

    网络系统 1. I/O多路复用1&#xff09;原始Socket模型通信方式2&#xff09;多进程模型3&#xff09;多线程模型4&#xff09;I/O多路复用select/pollepoll边缘触发和水平触发 2. Reactor和Proactor1&#xff09;Reactor模式2&#xff09;Reactor模式四种方案3&#xff09;单Re…...