C++中类的成员函数(方法)

2023-05-16

文章目录

          • 成员函数(方法)
          • 示例1:在结构体中引入成员函数
          • 示例2:类
          • 示例3:类内定义成员函数
          • 示例4:类内声明+类外定义显示内敛的成员函数
          • 示例5:类内声明+类外定义成员函数
          • 示例6:类与编译期的两遍处理
          • 示例7:成员函数与尾随返回类型
          • 示例8:使用 this 指针引用当前对象
          • 示例9:基于 const 的成员函数
          • 补充示例:基于 const 的成员函数重载
          • 示例10:成员函数的名称查找与隐藏关系
          • 示例11:在静态成员函数中返回静态数据成员
          • 示例12:成员函数基于引用限定符的重载

成员函数(方法)

● 可以在结构体中定义函数,作为其成员的一部分:对内操作数据成员,对外提供调用接口

– 在结构体中将数据与相关的成员函数组合在一起将形成类,是 C++ 在 C 基础上引入的概念

– 关键字 class

– 类可视为一种抽象数据类型,通过相应的接口(成员函数)进行交互

– 类本身形成域,称为类域

● 成员函数的声明与定义

了解内联:什么是内联、隐式内联和显式内联

– 类内定义(隐式内联)

– 类内声明 + 类外定义

注意:类内定义的成员函数为内联函数;类内声明 + 类外定义的成员函数默认为费内敛函数,也显示定义为内敛函数。

– 类与编译期的两遍处理

– 成员函数与尾随返回类型( trail returning type )

● 成员函数与 this 指针

– 使用 this 指针引用当前对象

– 基于 const 的成员函数重载

● 成员函数的名称查找与隐藏关系

– 函数内部(包括形参名称)隐藏函数外部

– 类内部名称隐藏类外部

– 使用 this 或域操作符引入依赖型名称查找

● 静态成员函数

– 在静态成员函数中返回静态数据成员

● 成员函数基于引用限定符的重载( C++11 )

示例1:在结构体中引入成员函数
#include <iostream>

struct myStr
{
    int x = 3;
    void print()
    {
        std::cout << x << std::endl;
    }
};

int main()
{
    myStr str;
    str.print();
}

输出:

3
示例2:类
#include <iostream>

class myStr
{
public:
    int x = 3;
    void print()
    {
        std::cout << x << std::endl;
    }
};

int main()
{
    myStr str;
    str.print();
}

输出:

3

结构体与类区别:结构体默认public,而class默认private

示例3:类内定义成员函数

其中,函数void print()属于类内定义的隐式内联函数。

#include <iostream>

class myStr
{
public:
	int x = 3;
	void print()
	{
		std::cout << x << std::endl;
	}
};

int main(int argc, char* argv[])
{
    myStr str;
	str.print();
}

输出:

3
示例4:类内声明+类外定义显示内敛的成员函数

header.h 内类声明

#pragma once
#include <iostream>

class myStr
{
public:
	int x = 3;
	void print();
};

inline void myStr::print()
{
	std::cout << x << std::endl;
}

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str;
	str.print();
}
示例5:类内声明+类外定义成员函数

header.h 内类声明

#pragma once
#include <iostream>

class myStr
{
public:
	int x = 3;
	void print();
};

source.cpp 类外定义

#include "header.h"

void myStr::print()
{
	std::cout << x << std::endl;
}

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str;
	str.print();
}
示例6:类与编译期的两遍处理

header.h 头文件改写为

#pragma once
#include <iostream>

class myStr
{
public:
    void print()
{
	std::cout << x << std::endl;
}
	int x = 3;
};

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str;
	str.print();
}

当程序执行到header.h 头文件第7行,理论上应该会报错,因为print()中x没有声明。之所以不报错,是由于编译器(编译期的两遍处理)第一遍处理函数和数据,但不处理函数内部的内容,第二次再处理函数内部内容。

示例7:成员函数与尾随返回类型

header.h 内类声明

#pragma once
#include <iostream>

class myStr
{
public:
	using myInt = int;
	myInt x = 3;
	myInt Add();
};

source.cpp 类外定义

#include "header.h"

// 错误写法:未定义标识符myInt
//myInt myStr::Add()
//{
//	return x + 1;
//}

// 正确写法1
//myStr::myInt myStr::Add()
//{
//	return x + 1;
//}

// 正确写法2(推荐):尾随返回类型
auto myStr::Add()->myInt
{
	return x + 1;
}

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str;
	std::cout << str.Add() << std::endl;
}
}

输出:

4
示例8:使用 this 指针引用当前对象

header.h 头文件写为

#pragma once
#include <iostream>

class myStr
{
public:
	void print() // 在成员函数中 隐式的传入了 this
	{
        // this指针是存放创建对象的地址;
        // this类型:this-> myStr *const,这里const表示指针不能被修改,但指针指向的内容可以修改
		std::cout << this << std::endl;
		std::cout << this->x << std::endl;
	}
	int x = 0;
};

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str1;//创建对象1,地址000000DF499FFB44
	str1.x = 3;
	std::cout << (&str1) << std::endl;
	str1.print();

	myStr str2;//创建对象2,地址000000DF499FFB64
	str2.x = 8;
	std::cout << (&str2) << std::endl;
	str2.print();
}

输出:

000000DF499FFB44
000000DF499FFB44
3
000000DF499FFB64
000000DF499FFB64
8

补充示例:

header.h 头文件写为

#pragma once
#include <iostream>

class myStr
{
public:
	void print(int x)
	{
		std::cout << x << std::endl;// 函数参数x,主程序输入为8
		std::cout << this->x << std::endl;// 对象数据成员x为0
	}
	int x = 0;
};

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str1;
	str1.print(8);
}

输出:

8
0
示例9:基于 const 的成员函数

header.h 头文件写为

#pragma once
#include <iostream>

class myStr
{
public:
    // this原本类型:this-> myStr *const
	void print( ) const // 在成员函数加入这个const,this类型将变为 const myStr *const
	{
        // this->x=8; // 打开注释,会报错,提示成员数据无法被修改
		std::cout << this->x << std::endl;// 对象数据成员x为0
	}
	int x = 0;
};

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str1;
	str1.print();
}

输出:

0
补充示例:基于 const 的成员函数重载

header.h 头文件写为

#pragma once
#include <iostream>

class myStr
{
public:

	void print() //this -> myStr *const
	{

	}
	void print() const //this -> const myStr *const
	{

	}
	int x = 0;
};

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str1;
	str1.print();
}

通过这个例子,了解const成员函数重载。

示例10:成员函数的名称查找与隐藏关系

成员函数的名称查找优先级:

函数内部(包括形参名称)-> 类内部名称 -> 类外部名称

意思很简单,就是如果成员函数内部存在x,则使用该x;若成员函数内部不存在x,则使用类内部名称;若成员函数内部与类内部名称都不存在x,则使用类外部定义的x。

header.h 头文件写为

#pragma once
#include <iostream>

int x = 2;
class myStr
{
public:

	void print() //this -> myStr *const
	{
    int x = 0;  
    std::cout << x << std::endl; // 成员函数内部x
    std::cout << this->x << std::endl;// 类内部名称x
    std::cout << ::x << std::endl;// 类外部定义的x
	}
    
	int x = 1;
};

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str1;
	str1.print();
}

输出:

0
1
2
示例11:在静态成员函数中返回静态数据成员

了解C/C++ 中 static 的用法全局变量与局部变量 | 菜鸟教程 (runoob.com)

header.h 头文件写为

#pragma once
#include <iostream>


class myStr
{
public:
    myStr()
    {
        x++;
        y += x;
    }
    
    static void print() 
    {
        std::cout << x << std::endl;
    }

    static int gety()
    {
        return y;
    }

    static int x;
    static int y;
};
// 静态成员数据类外初始化
int myStr::x = 0;
int myStr::y = 0;

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str1;
	myStr::print();// 统计创建对象的次数 1

	myStr str2;
	myStr::print();// 统计创建对象的次数 2

	// 累加x的值
	std::cout << myStr::gety() << std::endl;
}

输出:

1
2
3
示例12:成员函数基于引用限定符的重载

header.h 头文件写为

#pragma once
#include <iostream>

class myStr
{
public:

    void print() & // 左值引用
    {

    }

    void print() && // 右值引用
    {

    }
    void print() const & // 常量左值引用
    {

    }
    void print() const && // 常量右值引用
    {

    }

};

main.cpp 调用

#include "header.h"

int main(int argc, char* argv[])
{
	myStr str1;
	str1.print(); // void myStr::print() &

	myStr().print();// void myStr::print() &&

}

参考资料:

《C++ Primer 中文版》(第 5 版)
《C++基础与深度解析》深蓝学院课程

非静态成员函数 - cppreference.com

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++中类的成员函数(方法) 的相关文章

  • Vue+dataV:调用后台数据,数据赋值成功,但是组件上的数据更新失败

    问题描述 公司要做个数据看板 xff0c 因为在项目中应用到了dataV xff0c 在使用的过程中 xff0c 发现dataV的组件的数据 xff0c 若是来自自己定义的常量数据 xff0c 数据可以正常显示在组件中 但当数据来自于axi
  • Windows Server 2008搭建域控制器

    前言 1 为什么要建域 工作组的分散管理模式不适合大型的网络环境下工作 xff0c 域模式就是针对大型的网络管理需求设计的 xff0c 就是共享用户账号 xff0c 计算机账号和安全策略的计算机集合 域中集中存储用户账号的计算机就是域控器
  • -bash: zip: command not found提示解决办法

    bash zip command not found 是因为liunx服务器上没有安装zip命令 xff0c 需要安装一下即可 linux安装zip命令 xff1a apt get install zip 或yum install zip
  • 超全的数据库分类介绍

    数据库的分类 数据库通常分为层次式数据库 网络式数据库和关系式数据库三种 而不同的数据库是按不同的数据结构来联系和组织的 而在当今的互联网中 xff0c 最常见的数据库模型主要是两种 xff0c 即关系型数据库和非关系型数据库 数据库分类
  • suse11/12关闭防火墙

    suse11 关闭操作为 xff1a service SuSEfirewall2 setup stop service SuSEfirewall2 init stop 取消开机启动防火墙 xff1a chkconfig SuSEfirewa
  • pip download 只下载不安装命令的使用方法

    比如下载 django 1 8 11版本和simplejson 3 14 0版本的包 那么就将所需的包写入 requirement txt 那么我的requirement txt内容就是 xff1a django 61 61 1 8 11
  • k8s学习笔记

    九 deployment xff1a 声明式的升级应用 9 1 使用RC实现滚动升级 kubectl rolling update kubia v1 kubia v2 image 61 luksa kubia v2 使用kubia v2版本
  • k8s学习笔记---Statefulset:部署有状态的多副本应用

    10 1 什么是Statefulset StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器API 特点 xff1a 1 具有固定的网络标记 xff08 主机名 xff09 2 具有持久化存储 3 需要按顺序部署
  • Frp 内网穿透配置文件

    服务器配置frps ini common bind port 61 7000 token 61 12314 客户端连接需要配置使用的令牌 vhost http port 61 8080 客户端配置http 转发的时候必须配置该项 端口号为云
  • maven打包报错:Cannot construct org.apache.maven.plugin.war.util.WebappStructure as it does not have a no

    我的项目因为某些原因从本地删除掉了 xff0c 然后由SVN重新导入 xff0c 结果打包报错了 Cannot construct org apache maven plugin war util WebappStructure as it
  • Freertos任务切换异常问题

    最近调试运行了freertos的代码时发现程序不知为何任务切换不了 xff0c 经检查发现程序死在了断言中 xff0c 这个断言所处的函数是vTaskSwitchContext 这个函数的作用是任务切换用的 xff0c 断言的位置如下图所示
  • Vue+dataV:轮播表,调用后台数据,数据没有更新

    项目场景 xff1a 公司用Vue做前端项目 xff0c 要做一个数据看板 xff0c 其中有个模块是个数据轮播展示的 xff0c 研究了一下 xff0c dataV中的个轮播表 xff0c 可以达到这个效果 但使用dataV制作轮播表 问
  • 物联网下的操作系统

    1 freertos amazon 2 rt thread 配LWIP 3 liteOS 华为 系统freertospthreadsrt threadTCP IP开发平台 云Amazon FreeRTOSAliOS ThingsliteOS
  • STM32实时操作系统的FreeRTOS 和uCOS II的比较

    freeRTOS比uCOS II优胜的地方 xff1a 1 内核ROM和耗费RAM都比uCOS 小 xff0c 特别是RAM 这在单片机里面是稀缺资源 xff0c uCOS至少要5K以上 xff0c 而freeOS用2 3K也可以跑的很好
  • IntelliJ IDEA 2019.2.3中文乱码问题

    今天打开idea突然发现java文件里面的中文极其怪异 61 61 43 于是乎百度搜索不下十来篇文章 xff08 思路大概一致 甚至尝试 重装IDEA amp 重启电脑 来解决问题 但是我的idea貌似没什么反应 最后发现改Editor
  • 解决win10下 stlink 无法正常安装问题

    注 xff1a 自己解决问题做的笔记 xff0c 大神勿喷 有不足之处还望不吝赐教 一般win7下装的驱动都没问题 xff0c 但到了win10下问题殊出 大家都知道 xff0c win10是个问题系统 xff0c 还不够完善 xff0c
  • 极简TensorFlow学习教程-----TensorFow中Tensor与Numpy相互转换

    1 Numpy转Tensor TensorFlow 通过 convert to tensor 函数将Numpy转换为Tensor xff0c 代码如下 xff1a span class token keyword import span t
  • 知网、维普、万方文献一网打尽免费下载,亲测好用哦!

    今天给大家带来中国数据库 三驾马车 xff1a 知网 维普 万方三大数据库文献免费下载的方法 今天带小伙伴们走正规途径 简单介绍一下三大网站 知网 xff1a 期刊类型比较综合 xff0c 覆盖范围广 以科技信息为主 涵盖经济 文化 教育等
  • Linux 控制台命令:搜索历史命令 Ctrl + R

    Reference xff1a Linux 控制台神器 xff1a 搜索历史命令 Ctrl 43 R ctrl 43 r to search the history command Linux下的神器 ctrl 43 r reverse i

随机推荐

  • 匈牙利算法 & KM算法

    匈牙利算法 amp KM算法 1 匈牙利算法 xff08 Hungarian Algorithm xff09 2 KM 算法 xff08 Kuhn Munkres Algorithm xff09 Reference 带你入门多目标跟踪 xf
  • 树莓派64位系统安装pytorch & torchvision

    Miniconda安装 Miniconda源链接 测试发现很多版本安装会出现Illegal instruction错误 xff0c 不建议安装大于4 9的版本 顺利安装 Miniconda3 py37 4 9 2 Linux aarch64
  • 118. Pascal's Triangle (python)

    Given numRows generate the first numRows of Pascal s triangle For example given numRows 61 5 Return 1 1 1 1 2 1 1 3 3 1
  • Vue+dataV:环形图,调用后台的数据,数据不刷新问题

    项目场景 xff1a 制作环形图dv active ring chart xff0c 调用后台数据 xff0c 环形图上数据不更新 问题描述 环形图dv active ring chart的数据来自axios调用后台数据 xff0c 成功从
  • Ubuntu 16.04安装docker详细步骤与Ubuntu16.04 执行sudo apt-get update出现E: Sub-process returned an error code错误

    转载https blog csdn net jinking01 article details 82490688和https blog csdn net devil 08 article details 78431491 因需要安装open
  • 2.3 SVC中断

    SVC中断 SVC中断服务函数 通过SVC指令触发SVC中断 define vPortSVCHandler SVC Handler asm void vPortSVCHandler void PRESERVE8 ldr r3 61 pxCu
  • 解决virtualBox ubuntu桥接,nat不能上网问题

    开始配置网络的无论是桥接 xff0c nat模式都不能连接外网 xff0c 尝试了N方法无果 xff0c 最后猜想是不是网卡的设置有问题 结果果然是这里的问题 解决方案 xff1a 打开网络和共享中心 lt lt 更改适配器设置 lt lt
  • ProxmoxVE折腾记录(二)--版本升级

    PVE6 0升级 官方F amp Q https pve proxmox com wiki FAQ faq support table 升级说明 F amp Q10条 11条系统版本说明及升级参考 xff0c 这次准备升级到6 0 5 4的
  • casbin学习笔记

    安装 go get github com casbin casbin v2 span class token keyword import span span class token string 34 github com casbin
  • Linux用户和组管理

    Linux用户和组管理 一 实验目的 1 掌握添加用户 修改用户和删除用户信息的方法 2 掌握添加组 修改组户和删除组的方法 3 掌握修改用户权限的方法 二 实验内容 在字符界面下 xff0c 使用常用的Linux操作命令 xff0c 完成
  • 【Docker环境部署】kong网关搭建,konga安装(参考官网)

    一 下载镜像 docker pull postgres 9 6 docker pull kong docker pull pantsel konga 二 docker安装kong 1 创建网桥 docker network create k
  • 【VBA编程】VBA基础语法(二)

    一 VBA中的内置函数 合理使用函数不但可以节省处理数据的时间 xff0c 提高工作效率还可以降低编程的难度 xff0c 减少编写代码的工作量 例如想知道当前系统时间 xff1a Sub NowTime MsgBox 34 现在的时间是 x
  • 【VBA编程】Sub过程

    过程就是做一件事的经过 xff0c 由不同的操作按先后顺序排列 组合起来 VBA的基本过程有Function过程和Sub过程 过程保存在模块里 Excel对象 xff08 或窗体对象 xff09 也能保存过程 为了避免发生错误 xff0c
  • 【VBA编程】自定义函数,Function过程

    Function过程也称为函数过程 编写一个Function过程 xff0c 就是编写了一个函数 函数可以完成很多复杂的计算 xff0c 如想求A列的和 xff0c 可以使用SUM函数 xff1b Function过程同Sub过程一样 xf
  • 查看网站的技术架构

    想要快速查看网站使用的架构 xff0c 可以在浏览器中添加Wappalyzer插件 以火狐浏览器为例 火狐浏览器 更多工具 61 gt 面向开发者扩展 61 gt 查找Wappalyzer 61 添加 xff0c 即可 红框中即 Wappa
  • Linux服务器查看日志的几种方法

    1 进入日志文件所在的文件目录 xff0c 比如 xff1a cd opt tomcat7 logs 2 通过命令打开日志 xff0c 分析需求场景打开需要的日志 比如 xff1a tail f catalina out 3 常用命令一 x
  • Postman设置网络代理

    1 什么是网络代理 xff1f 在一个基本的网络会话中 xff0c 一个客户端发送一个请求到服务器 xff0c 服务器返回一个响应 xff1b 一个代理服务是一个应用程序或者系统 作为一个中介在你的电脑和互联网之间 客户端和服务器 xff0
  • Postman中的authorization

    1 概述 Authorization是验证是否拥有从服务器访问所需数据的权限 当发送请求时 xff0c 通常必须包含参数 xff0c 以确保请求具有访问和返回所需数据的权限 Postman提供了授权类型 xff0c 可以轻松地在Postma
  • 无法将非静态数据成员声明为 inline

    示例代码 xff1a span class token macro property span class token directive hash span span class token directive keyword inclu
  • C++中类的成员函数(方法)

    文章目录 成员函数 xff08 方法 xff09 示例1 xff1a 在结构体中引入成员函数示例2 xff1a 类示例3 xff1a 类内定义成员函数示例4 xff1a 类内声明 43 类外定义显示内敛的成员函数示例5 xff1a 类内声明