做企业网站步骤,成都 网站建设 公司哪家好,简单的视频网站能不能用dw做,凡科做的网站提示证书错误文章目录 2. 虚函数vs纯虚函数3. 重写vs重载vs隐藏3.1. 为什么C可以重载#xff1f; 4. 类变量vs实例变量5. 类方法及其特点6. 空类vs空结构体6.1. 八个默认函数#xff1a;6.2. 为什么空类占用1字节 7. const作用7.1 指针常量vs常量指针vs常量指针常量 8. 接口vs抽象类9. 浅… 文章目录 2. 虚函数vs纯虚函数3. 重写vs重载vs隐藏3.1. 为什么C可以重载 4. 类变量vs实例变量5. 类方法及其特点6. 空类vs空结构体6.1. 八个默认函数6.2. 为什么空类占用1字节 7. const作用7.1 指针常量vs常量指针vs常量指针常量 8. 接口vs抽象类9. 浅拷贝vs深拷贝9.1. 深拷贝应用场景 10. 写时拷贝 2. 虚函数vs纯虚函数
引入虚函数是为了动态绑定。引入纯虚函数是为了派生接口即子类仅仅只是继承函数的接口。
3. 重写vs重载vs隐藏
重写发生继承关系中子类重写父类的方法。重载发生在同一个类中函数名相同但参数个数或类型不同。隐藏子类函数屏蔽了与其同名的基类函数有以下两种情况 1、参数不同基类函数被隐藏而不是重载。 2、参数相同但基类函数没有virtual关键字基类函数被隐藏而不是重写。
3.1. 为什么C可以重载
C引入了命名空间以及作用域比如类作用域命名空间作用域。函数在编译期间链接符号的时候会在符号后追加一些特殊标识比如add函数变成add123。
4. 类变量vs实例变量
类变量静态变量是类的所有实例共有的。实例变量对象变量是每个实例单独拥有的。
5. 类方法及其特点
类方法静态方法就是用static关键字修饰的方法特点类方法不能访问实例变量只能访问类变量类方法可以由类名直接调用也可以由实例对象调用。
6. 空类vs空结构体
空类默认private。空结构体默认public。
6.1. 八个默认函数
构造函数 【A();】析构函数 【~A();】拷贝构造函数 【A (const A);】重载赋值运算符 【Aoperator (const A);】重载取址运算符 【A* operator ();】重载取址运算符const 【const A* operator () const;】移动构造函数C11) 【A(A);】重载移动赋值运算符C11【A operator (const A);】
6.2. 为什么空类占用1字节
因为如果对象完全不占用内存空间空类就无法取得实例的地址this指针失效因此不能被实例化。而类的定义是由数据成员和成员函数组成的在没有数据成员情况下还可以有成员函数因此仍然需要实例化。
7. const作用
限定变量不可修改。限定成员函数不可修改数据成员后置const。成员函数的返回值类型是const则返回值不是左值前置const。用const对函数的参数修饰表面是输入参数在函数内不可写。
7.1 指针常量vs常量指针vs常量指针常量
指针常量即指针本身是常量所以指针的值内存地址不能改变示例如下。 int a 10, b 20;int* const p a;p b; //错误指针存放的内存地址不可变*p 100; //正确内存地址存放的内容可以改变常量指针即指向常量的指针不能通过指针修改指向的内容示例如下。 const int a 10;int b 20;const int* p a;p b; //正确 指针存放的内存地址可变*p 100; //错误指针指向的内容不可变b 100; //正确可以通过原来的声明修改常量指针常量即指向常量的指针本身也是常量不能通过指针修改指向的值指针的值不能改变示例如下。 const int a 10;int b 20;const int* const p a;p b; //错误 指针存放的内存地址不可变*p 100; //错误指针指向的内容不可变8. 接口vs抽象类
纯虚函数是在基类中声明但没有定义的虚函数要求子类必须提供实现。抽象类带有纯虚函数的类。 抽象类作用为了扩展和重用。接口没有数据成员成员函数都是公有的、都是纯虚函数虚析构函数除外是完全抽象的类。 接口作用只提供了一种规范实现接口的类必须实现接口中的所有方法。代码如下。
// ConsoleApplication5.cpp : 此文件包含 main 函数。程序执行将在此处开始并结束。
//#define _CRTDBG_MAP_ALLOC
#include stdlib.h
#include crtdbg.h
#includeiostream
using namespace std;//抽象类
class Shape
{
protected: //数据成员价格和面积double price; double area; public://构造函数Shape() :price(100),area(0) {} //虚析构函数virtual ~Shape() { printf(%s\n, Delete shape); } //纯虚函数获取图形描述和获取价格virtual void getDescription() 0; virtual void getPrice() 0;
};//接口
class Draw
{
public://虚析构函数virtual ~Draw() { printf(%s\n, Delete Draw); }//纯虚函数输出图形周长virtual void drawLen() 0;
};//具体类
class Circle : public Shape,public Draw
{
private:double radius; public:Circle(double r) : radius(r) { area 3.14 * radius * radius; price 100 area * 6; }~Circle() { printf(%s%f\n, Delete circle with radius ,radius); }void getDescription() { printf(%s%f\n, Circle with radius ,radius);}void getPrice(){ printf(%s%f%s%f\n, Circle with area , area, price ,price); }void drawLen() { printf(%s%f\n, Circle with len , 2 * 3.14 * radius); }
};int main() {Circle c(5.0);Shape* s c; //基类Shape指针指向子类Circle对象s-getDescription();s-getPrice();Draw* d c; //基类Draw指针指向子类Circle对象d-drawLen();_CrtDumpMemoryLeaks();return 0;
}
程序执行结果如下图。 9. 浅拷贝vs深拷贝
浅拷贝只是将指针拷贝指向同一块内存。深拷贝是直接将内存拷贝一份。
9.1. 深拷贝应用场景
**【注意】**当类成员变量是指针为它动态分配内存时有以下两种bug情况 1、若使用默认的重载赋值运算符进行浅拷贝即a和b指向同一内存但b曾指向的内存不会被删除造成内存泄漏若一方离开了它的生存空间使用析构函数释放资源另一方会变成悬空指针导致未定义行为同时当另一方调用析构函数时会因重复释放同一堆空间而触发中断。 2、若使用默认的拷贝构造函数进行浅拷贝会重复释放同一内存。 所以为避免这两种bug情况需要进行深拷贝。修改一个对象不会影响到另一个对象时进行深拷贝以确保每个对象都有自己独立的数据副本。
10. 写时拷贝
在使用系统重要的dll或者系统一些函数的时候系统为了节省空间和提高性能会直接映射一份共享地址但当我们对其进行修改时会触发写时拷贝会拷贝一份给我们进程内使用防止我们去修改共享的地址影响整个系统。