C++复习类与对象基础

类的成员函数为什么需要在类外定义

1.1 代码组织与可读性​

​类内定义​:适合 ​短小简单的函数​(如 getter/setter),能直观体现类的接口设计。

​类外定义​:当函数体较复杂时,将实现移到类外(如 .cpp 文件)可保持 ​类声明简洁,便于快速理解类的核心接口,避免代码臃肿。

1.2 编译依赖与构建速度​

​类内定义​:若函数体直接写在头文件中,每次修改函数逻辑时,所有包含该头文件的代码都需要重新编译,导致 ​编译时间大幅增加。

​类外定义​:将实现放在 .cpp 文件中,修改实现时仅需重新编译该 .cpp 文件,显著提升大型项目的 ​构建效率。

1.3 避免重复定义(ODR 规则)​​

​类内定义​:若头文件被多个源文件包含,类内定义的成员函数会被视为 ​内联函数​(inline)。虽然内联允许重复定义,但过度使用可能导致 ​代码膨胀。

​类外定义​:在 .cpp 文件中定义函数,确保 ​仅有一份实现,严格遵循单一定义规则(One Definition Rule, ODR)。

1.4 封装与信息隐藏​

​类外定义​:可将实现细节隐藏在 .cpp 文件中,仅通过头文件暴露接口。这种方式 ​减少头文件暴露的内部信息,增强代码的封装性。

2.类内成员函数是否需要同时实现const版本和非const版本

2.1 非const对象可以调用const修饰的成员函数,但是const对象只能调用const成员变量

2.2 当const函数与非const函数代码逻辑几乎相同时

若两个版本的函数逻辑几乎相同(仅返回类型或对象 const 属性不同),可通过 复用代码​减少冗余

1.非const函数调用const函数

cpp 复制代码
class MyArray {
public:
    // const 版本实现核心逻辑
    const int& operator[](size_t index) const { 
        // 复杂逻辑(如边界检查)
        return data[index]; 
    }

    // 非 const 版本复用 const 版本,用 const_cast 移除返回类型的 const
    int& operator[](size_t index) {
        return const_cast<int&>( 
            static_cast<const MyArray&>(*this)[index] 
        );
    }
};

1.通过static_cast<const MyArray&>调用operator.[],如果返回值类型一个是const可通过const_cast<int&>进行类型转换

2.万能引用

cpp 复制代码
class MyArray {
private:
    template <typename Self>
    static auto& get_element(Self&& self, size_t index) {
        // 复杂逻辑(如边界检查)
        return self.data[index];
    }

public:
    int& operator[](size_t index) { 
        return get_element(*this, index); 
    }

    const int& operator[](size_t index) const { 
        return get_element(*this, index); 
    }
};

.*运算符

cpp 复制代码
class A
{
public:
	void func()
	{
		cout << "A::func()" << endl;
	}
};

//typedef void(A::*PF)(); //成员函数指针类型
using PF = void(A::*)();

int main()
{
	// C++规定成员函数要加&才能取到函数指针
	PF function = &A::func;
	A aa;
	(aa.*function)();
}

初始化列表初始化引用的问题

cpp 复制代码
class Myclass {
public:
	Myclass(int x):_x(x)
	{}
private:
	int& _x;
};


int main()
{
	Myclass a(1);
	return 0;
}

非const引用引用临时变量,编译器仅检查 ​直接引用绑定​ 的合法性(如 int& r = 1; 会报错),但无法追踪间接的悬垂引用风险。但是可以传字面量,但是成员变量是const int&,这样就可以延长生命周期,但最好将参数改为与成员变量相同的形参,如int &成员初始化传参就传int&,这样传字面量编译器也会警告

相关推荐
Code Slacker5 分钟前
LeetCode Hot100 —— 普通数组(面试纯背版)(五)
数据结构·c++·算法·leetcode·面试
秦苒&17 分钟前
【C语言】详解数据类型和变量(一):数据类型介绍、 signed和unsigned、数据类型的取值范围、变量、强制类型转换
c语言·开发语言·c++·c#
智者知已应修善业1 小时前
【删除有序数组中的重复项 II之O(N)算法】2024-1-31
c语言·c++·经验分享·笔记·算法
爱装代码的小瓶子1 小时前
【c++进阶】C++11新特性:一切皆可{}初始化
开发语言·c++·visual studio
xiaoye-duck1 小时前
吃透C++类和对象(中):构造函数与析构函数深度解析
c++
AA陈超1 小时前
Lyra Starter Game 中 GameFeature 类(如 ShooterCore)的加载流程
c++·笔记·学习·ue5·虚幻引擎
加成BUFF1 小时前
C++入门讲解3:数组与指针全面详解
开发语言·c++·算法·指针·数组
天若有情6732 小时前
我发明的PROTO_V4协议:一个让数据“穿上迷彩服”的发明(整数传输协议)
网络·c++·后端·安全·密码学·密码·数据
加油=^_^=2 小时前
【C++11】特殊类设计 | 类型转换
c++·单例模式·类型转换
加成BUFF2 小时前
C++入门详解2:数据类型、运算符与表达式
c语言·c++·计算机