个人知识库 个人知识库
首页
关于
  • C语言
  • CPlusPlus
  • Linux
  • PHP
  • Nginx
  • MySQL
  • Redis
  • Docker
  • Kubernetes
  • SRS
阅读
常用工具
  • 分类
  • 标签
  • 归档
GitHub

Agnes001

坚持是一件很伟大的事业
首页
关于
  • C语言
  • CPlusPlus
  • Linux
  • PHP
  • Nginx
  • MySQL
  • Redis
  • Docker
  • Kubernetes
  • SRS
阅读
常用工具
  • 分类
  • 标签
  • 归档
GitHub
  • C语言

  • CPlusPlus

    • 基础特性

      • 枚举
      • 字符指针
    • vs2019设置
    • C++11特性

    • 并发编程

    • 引用
    • 类和对象
      • 1 概念
      • 2 构造函数
        • 2.1 初始化列表
        • 2.2 默认构造函数
        • 2.3 拷贝构造函数
        • 2.4 拷贝赋值运算符
        • 2.4 移动构造函数
      • 3 访问权限
      • 4 静态成员变量和成员函数
        • 4.1 静态成员变量
        • 4.2 静态成员函数
      • 5 const修饰的成员函数
        • 5.1 const修饰成员函数
        • 5.2 const修饰函数返回值
    • 友元和运算符重载
    • 继承
    • 继承和多态
    • 模板
    • C++基础总结
    • 类型转换
    • 异常
    • 容器
    • 算法
    • C++程序设计
    • C++ Primer总结
    • 编程技巧
    • 标准库体系结构与内核分析
    • 设计模式
    • cmake配置C++工程
    • libcurl的使用总结
    • web开发框架--drogon
    • log4cplus使用
    • C++数据类型
    • 函数
    • 线程
    • 进程
    • 文件操作
    • 日常问题记录
    • Cpp案例程序
    • 多线程
    • 侯捷c++11新特性
    • 侯捷stl
  • Lua技术栈

  • edoyun

  • 内存管理

  • 数据结构

  • 网络编程

  • Linux

  • 池化技术

  • 操作系统

  • python

  • 编程技术
  • CPlusPlus
Agnes001
2021-12-30

类和对象

# 1 概念

  1. class 封装的本质,在于将数据和行为,绑定在一起然后能过对象来完成操作。可以达到,对内开放数据,对外屏蔽数据,对外提供接口。
  2. struct和class关键字区别
  • 在用struct定义类时,所有成员的默认属性为public,希望直接访问其内部数据使用struct
  • 在用class定义类时,所有成员的默认属性为private,需要屏蔽内部数据,提供接口使用class

# 2 构造函数

主要完成数据初始化,在对象创建时自动调用构造函数。

# 2.1 初始化列表

当类成员中含有一个const对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化,因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。
初始化列表中的初始化顺序,与声明顺序有关,与前后赋值顺序无关。

# 2.2 默认构造函数

A() = default;//使用默认构造函数
A() = delete; //禁止使用默认构造函数
A(const A&)=delete;//表示删除默认拷贝构造函数,即不能进行默认拷贝
A& operator=(const A&)=delete;//表示删除默认赋值函数

# 2.3 拷贝构造函数

由己存在的对象,创建新对象。也就是说新对象,不由构造器来构造,而是由拷贝构造器来完成。

提示

拷贝构造函数的应用场景

  1. 场景1
void test1()
{
	Test t1(10, 20);
	//⽤对象t1初始化对象t2
	Test t2(t1); //也可写成Test t2 = t1; 等价
}
  1. 场景2
void func(Test t)//Test t = t1; //Test t 的拷贝构造函数
{
	cout << "func begin..." << endl;
	t.printT();
	cout << "func end..." << endl;
}
  1. 场景3-匿名对象
Test func2()
{
	cout << "func2 begin..." << endl;
	Test temp(10, 20);
	temp.printT();
	cout << "func2 end..." << endl;
	return temp;
}//返回的是匿名对象,匿名的对象=temp,调用匿名对象的拷贝构造函数

void test3()
{
	cout << "test3 being.. " << endl;
	func2();// 返回一个匿名对象。 当一个函数返回一个匿名对象的时候,函数外部没有任何变量去接收它,这个匿名对象将不会再被使用,(找不到),编译会直接将个这个匿名对象回收掉,而不是等待整个函数执行完毕再回收.	
	cout << "test3 end" << endl;
}

# 2.4 拷贝赋值运算符

需要分清赋值还是初始化

// 场景1
t3 = t1; //调用的不是t3拷贝构造函数,而是t3的赋值操作符函数

// 场景2
void test6()
{
	cout << "test6 begin..." << endl;
	Test t1;//t1已经被初始化了。

	t1 = func2(); //t1已经被初始化了,所以func2返回的匿名对象不会再次转正,而依然是匿名对象。
					//所以t1会调用等号操作符,t1.operator=(匿名对象), 然后编译器会立刻回收掉匿名对象

	t1.printT();
	cout << "test6 end.." << endl;
}

// 以上两种情况调用的是赋值操作
//=赋值操作符
void operator=(const Test &another)
{
    m_x = another.m_x;
    m_y = another.m_y;
}

结论

  1. 函数的返回值是⼀个元素(复杂类型的), 返回的是⼀个新的匿名对象(所以会调⽤匿名对象类的copy构造函数)
  2. 有关匿名对象的去和留
    如果⽤匿名对象初始化另外⼀个同类型的对象,匿名对象转成有名对象
    如果⽤匿名对象赋值给另外⼀个同类型的对象,匿名对象被析构

# 2.4 移动构造函数

右值引用资料:https://www.cnblogs.com/qicosmos/p/4283455.html

# 3 访问权限

注意

关于类成员函数中访问同类对象的私有成员,主要包含以下几种场景

  1. 在C++的类的成员函数中,允许直接访问该类的对象的私有成员变量。
  2. 在类的成员函数中可以访问同类型实例的私有变量。
  3. 拷贝构造函数里,可以直接访问另外一个同类对象(引用)的私有成员。
  4. 类的成员函数可以直接访问作为其参数的同类型对象的私有成员。

关于该问题(知识点)的讨论和或解释:

  1. 私有是为了实现“对外”的信息隐藏,或者说保护,在类自己内部,有必要禁止私有变量的直接访问吗?
  2. C++的访问修饰符的作用是以类为单位,而不是以对象为单位。
  3. 每个类的对象都有自己的存贮空间,用于存储内部变量和类成员;但同一个类的所有对象共享一组类方法,即每种方法只有一个源本。
  4. 访问权限是相对于类而言,而非对象!

# 4 静态成员变量和成员函数

# 4.1 静态成员变量

  1. static 成员变量实现了同类对象间信息共享。
  2. static 成员类外存储,求类大小,并不包含在内。
  3. static 成员是命名空间属于类的全局变量,存储在 data 区。
  4. static 成员只能类外初始化。
  5. 可以通过类名访问(无对象生成时亦可),也可以通过对象访问。

# 4.2 静态成员函数

  1. 静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员, 完成对静态数据成员的封装。
  2. 静态成员函数只能访问静态数据成员。原因:非静态成员函数,在调用时this 指针被当作参数传进。而静态成员函数属于类,而不属于对象,没有 this 指针。

C++类对象中的成员变量和成员函数是分开存储的
成员函数:存储于代码段中。
成员变量:

  • 普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式
  • 静态成员变量:存储于全局数据区中

# 5 const修饰的成员函数

# 5.1 const修饰成员函数

在成员函数的后边加上const

  1. const修饰成员函数时是修饰成员函数的this指针所指向的对象,也就是保证在调用这个const成员函数的对象时不会被改变。
  2. const对象可以调用const修饰的成员函数,不能调用非cosnt修饰的成员函数。
  3. 非const对象可以调用const修饰的成员函数,和非const修饰的成员函数
  4. 常成员函数的const和non-const版本同时存在时,const object只能调用const版本,non-const object只能调用non-const版本。 注意:
  5. const放在函数后边,该函数为只读函数,不允许修改其中的数据成员的值。
  6. const放在函数前面,修饰的是返回值,表示返回的是指针所指向值是常量,即表示返回值不可改变。

# 5.2 const修饰函数返回值

  1. 如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。
  2. 如果给以“指针传递”方式的函数返回值加const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
  3. 但是返回值不是内部数据类型,例如:A get_string(void),这样会产生一个临时的对象用来存放返回的数据,会调用拷贝构造函数,这样效率会低,所以采用“引用传递”A &get_string(void),如果加上const那么返回值的内容就不会被改变const A &get_string(void)。
编辑此页
#class
引用
友元和运算符重载

← 引用 友元和运算符重载 →

Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式