栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

文章目录
          • 成员函数(方法)
          • 示例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 

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

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

输出:

3
示例2:类
#include 

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 

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 

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 

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 

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 

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 

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 

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 

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 

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 

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 


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 

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1008906.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号