c++类和对象以及模板

张开发
2026/4/18 4:16:16 15 分钟阅读

分享文章

c++类和对象以及模板
类和对象在讨论类和对象时需要重点理解STL库中的容器以及面向对象的三大特性封装、继承和多态。类的特性主要体现在其整体性上。与外部函数严格要求的调用顺序不同类域作为一个整体其成员函数和成员变量可以在任何位置被识别无需考虑调用顺序问题。封装通过将对象的属性和方法相结合来实现使对象更加完善。通过访问限定符public、private、protect可以有选择地向外部用户提供接口。其中public公开访问private和protect受限访问具体区别将在继承和多态中详述访问权限的作用域从当前限定符开始直到下一个限定符为止。值得注意的是class默认访问权限为privatestruct默认访问权限为public保持与C语言兼容类内定义的函数默认为内联函数封装的核心在于将数据与操作方法有机结合隐藏对象属性和实现细节仅对外公开交互接口。这种管理方式让类的使用更加便捷。对象大小仅包含成员变量不包括成员函数。空对象占用1字节空间仅用于标识对象存在。关于this指针不能显式传递于形参和实参可在函数内部显式使用作为形参存储在函数调用栈帧中C与C的实现本质相同区别在于C自动处理指针传递类的六个默认成员函数构造函数初始化特性与类同名无返回值包括void对象实例化时自动调用支持重载未显式定义时编译器生成默认构造函数析构函数清理特性名称格式~类名无参数和返回类型不可重载每个类唯一对象生命周期结束时自动调用未显式定义时编译器生成默认析构函数对于包含自定义类型的类构造时会递归调用自定义类型的构造函数析构时先释放自身再释放自定义类型成员避免非法访问拷贝构造拷贝构造是构造函数的一个重要重载形式拷贝构造函数的参数只能有一个而且必须是类类型对象的引用若使用传值会直接报错因为会引发无穷递归调用未显示定义时编译器生成默认拷贝构造函数默认的会进行值拷贝浅拷贝自定义类型会去调用它的赋值重载对于构造函数的初始化有不同的方式我简单用代码构建一下class test{ public: test(int t,int k) : val(t),key(k){} test(int t) { val t; } private: int val; int key; };看了这两个构造方式想必大家也理解了第二个就和正常函数一样而第一个用的是成员初始化列表,而代表初始化列表开始初始化方式用的是两个初始化成员变量之间用隔开。还要提及构造函数的一个特点他是支持隐式类型转换的class test{ public: test(int t) : val(t){} private: int val; }; int main() { test t 1; return 0; }像这样整形转化为自定义类型此处的1会构造一个test的临时对象再拷贝构造t但是部分编译器会做优化将其转变为用1直接构造test对象。如果想禁止这种行为可以使用关键字explicit会禁止隐式类型转换。静态成员变量在类里声明在全局定义属于类类的每个对象共享一个静态成员变量且存储在静态区静态成员函数没有了this指针访问时只需指定类域和访问限定符即可这两个一般成对出现。友元类内部类是外部类的天生友元使用friendly对其他类进行声明说明其他类是该类的友元类对象普通对象就像上面的test t所以我们讲特殊的匿名对象和临时对象这两个对象都有一个共同之处都具有常性。匿名对象生命周期只在当前语句行具有常性const引用的匿名对象会延长自己的生命周期生命周期在当前局部域内存操作符也说一下创建对象常用的操作符new它和delete配对如class test{ public: test(int t) : val(t){} private: int val; }; int main() { test* t new test(1); delete t; return 0; }和mallocfree一样他们也是一组关于内存开辟释放的操作符有new一定要delete否则就会造成内存泄漏。模板与模板特化说到模板首先要清楚模板的关键词template下面简单写一个模板templateclass T,class K // typename T class test{ public: test(T t,K k) : val(t),key(k){} private: T val; K key; };看到这段代码肯定会困惑template后面那个是做什么用的,其实用typename会更好理解他就是代表一个类型至于是什么类型看你传的参数是什么类型而自动推导的但是实际上模板做的工作是以你传入的类型重新构建一份代码每次传递的不一样都会额外生成一个那如果有一些类型需要比正常的多出一些功能怎么办又或者处理方式有差异怎么办那就得提到模板的特化了特化有两种一个是全特化一个是偏特化我分别写出来看完大家想必也会有一些自己的理解了。全特化#include iostream // 通用模板 template typename T class MyTemplate { public: void print() { std::cout 普通模板 std::endl; } }; // 全特化版本int 类型 template class MyTemplateint { public: void print() { std::cout int全特化模板 std::endl; } }; int main() { MyTemplatedouble obj1; MyTemplateint obj2; obj1.print(); // 输出: 普通模板 obj2.print(); // 输出: int全特化模板 }偏特化:#include iostream // 通用模板 template typename T class MyTemplate { public: void print() { std::cout 普通模板 std::endl; } }; // 偏特化版本指针类型 template typename T class MyTemplateT* { public: void print() { std::cout 指针模板 std::endl; } }; int main() { MyTemplatedouble obj1; MyTemplateint* obj2; obj1.print(); // 输出: 普通模板 obj2.print(); // 输出: 指针模板 }显而易见全特化是指把他完全特化为具体的类型偏特化是对部分模板参数进行特化而不是具体的类型。如果上面有误希望点出你我共勉一同进步。

更多文章