C++——类
2024-09-06 06:01:10
1.类和结构体,只有的默认访问权限的区别
2.类内不能定义和类外类型名相同的类型名。为什么?typedef机制?
typedef double money;
class Account
{
private:
typedef double money;//❌
}
3.变量名一致时的调用(不推荐相同的变量名)
pos height;
class Screen {
void Screen::dummy_fcn(pos height);
private:
pos cursor = ,height=, width=;
}
void Screen::dummy_fcn(pos height)
{
cursor=width*height;//传入参数
cursor=width*this->height;//成员
cursor=width*Screen::height;//成员
cursor=width*::height;//全局变量
}
4.初始化和赋值的区别
class ConstRef{
public:
ConstRef(int ii);
private:
int I;
const int ci;
int &ri;
}
ConstRef:: ConstRef(int ii){
I=ii;
ci=ii;//错误
ri=i; //错误
} ConstRef:: ConstRef(int ii):I(ii),ci(ii), ri(i) { }//正确
5.初始化列表的顺序与参数定义的顺序一致
class X {
int i;
int j;
public:
X(int val):j(val),i(j){}//本想val->j->i,实际是:j->i,val->j
}
6.默认构造函数、委托构造函数、合成的默认构造函数
class Sales_data{
Sales_data(std::string s, unsigned int, double price): bookNo(s), units_sold(cnt), revenue(int*price) { }
Sales_data():Sales_data(" ",,){ }//委托构造函数
}
6.1 三五法则
- 三个控制类拷贝的基本操作:拷贝构造函数;赋值拷贝运算符;析构函数
//类值的类
class HasPtr {
public:
HasPtr(const std::string &s=std::string()): ps(new std::string(s)),i() {}//构造函数1
HasPtr(const HasPtr &p):ps(new std::string(*p.ps)),i(p.i){} //构造函数2
HasPtr &operator=(const HasPtr &);//赋值拷贝运算符 ~HasPtr() { delete ps; }//此虚构函数必须同时定义一个对应的构造函数和拷贝复制运算符 private:
std::string *ps;
int i;
};
需要析构函数的类也需要赋值和拷贝操作;
需要赋值操作的类也需要拷贝操作,反之亦然;
HasPtr f(HasPtr hp)//传值,拷贝
{
HasPtr ret = hp;//再拷贝
return ret;//ret和hp都被销毁
}
HasPtr p("something");
f(p);//f结束,p.ps被销毁
HasPtr q(p);//p 和 q都指向无效内存---------------->如何解决?
7.默认初始化、值初始化
7.1 默认初始化
- 不使用初值定义非静态变量 int i;
- 类成员为类类型,使用合成的默认构造函数时?
- 没有在构造函数中显示初始化时
7.2 值初始化
- 数组初始化中,提供的值数量少于数组大小
- 不使用初始值定义局部静态变量
- 通过T()显式求是初始化
8.当类只含有内置类型或复合类型的成员时,编译器是不会为类合成默认构造函数的。因为:内置类型可以有自己的默认初始化,复合类型有给出的显示的构造函数进行初始化(如果没给,而复合类型中的成员又不是内置类型,说白了,找不到初始值的话,就会报错)
8.1 B()没有给b_member初值
8.2 去NoDefault里找初值。发现NoDefault的构造函数里也没有给初值:报错
9.聚合类
所有成员public,没有构造函数,没有类内初值,没有基类,没有virtual函数
10.字面值常量类
11.类的静态成员
- 静态成员可以是不完全类型,可以是类本身(指针也可以,但普通数据成员不行)
- 静态成员可以作为默认实参(因为可以提取值,但普通成员不行)
12.析构
- 析构函数不接受参数,不能被重载
- 隐式销毁一个内置指针类型,不会delete它所指向的对象(智能指针会?)
- 如果一个类需要自定义析构函数,那它也需要自定义拷贝构造函数、拷贝赋值运算符
13.阻止拷贝-delete(不用private是因为友元可以访问)
struct NoCopy {
NoCopy() = default; //使用合成的默认构造函数
NoCopy(const NoCopy&) = delete; //阻止拷贝//不要声明为private
NoCopy &operator = (const NoCopy&) = delete;//阻止赋值//不要声明为private,成员函数、友元函数调用会出错
~NoCopy() =default;//如果是delete,就不能销毁其对象了
};
- 类成员的析构函数是delete或private,则合成的析构函数将会是delete
- ------------拷贝构造------------------------,----------拷贝构造------------------
- ------------析构函数------------------------,----------拷贝构造------------------
- ------------拷贝赋值运算符是delete或private或const &,----------拷贝赋值运算符----------------
- ------------析构函数是delete或private,或有引用成员且没有类内初始化器,或有const成员且类型未显示定义默认构造函数,则合成的默认构造函数将会是delete
- 析构函数不能是delete
13.拷贝控制和资源管理:
13.1 行为像值的类:有自己的状态,完全独立。
//类值的类
class HasPtr {
public:
HasPtr(const std::string &s=std::string()): ps(new std::string(s)),i() {}//构造函数1
HasPtr(const HasPtr &p):ps(new std::string(*p.ps)),i(p.i){} //构造函数2
HasPtr& operator=(const HasPtr &);//赋值拷贝运算符
~HasPtr() { delete ps; }//此虚构函数必须同时定义一个对应的构造函数和拷贝复制运算符
private:
std::string *ps;
int i;
};
HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
auto newp = new string(*rhs.ps);//为了避免rhs和*this是同一个对象
delete ps;
ps = newp;
i = rhs.i;
return *this;
}
13.2 行为像指针的类:共享状态,改变副本即改变原值。(对原值进行不同状态下的操作)
最好的办法:shared_ptr
直接管理资源:引用计数(存放在哪里——动态内存)
//类指针的类
class HasPtr {
public:
HasPtr(const std::string &s=std::string()): ps(new std::string(s)),i(),use(new std::size_t()) {}//构造函数1
HasPtr(const HasPtr &p) :ps(new std::string(*p.ps)), i(p.i), use(p.use) { ++*use; } //构造函数2
HasPtr& operator=(const HasPtr &);//赋值拷贝运算符 ~HasPtr() {
if (--*use == )
{
delete ps;
delete use;
}//此虚构函数必须同时定义一个对应的构造函数和拷贝复制运算符
} private:
std::string *ps;
int i;
std::size_t *use;//引用计数
};
HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
++ *rhs.use;//增加右侧对象的引用计数
if (--*use == )//先减少原本对象的引用计数(可能本来是别的对象,更改之后就要把原来的减一)
{
delete ps;
delete use;
}
//拷贝
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
涉及资源管理的操作:构造、赋值、析构、交换(适合指针)
最新文章
- Java基础学习--抽象类与抽象函数
- 开发人员必读openstack网络基础
- 关于VR边纹理材质的渲染
- java运算符总结
- Eclipse c++环境搭建 并加载OpenCV库 2015最新
- # 36氪开放日 • 杭州 • 11月10日 # 谈谈参会感受
- [转]在ITunes播放中前进、后退五秒的快捷键
- JAVA 初识类加载机制 第13节
- PHP常用数组(Array)函数整理
- jQuery中的自定义插件之----工厂方法(Factory Widget)
- 树形结构模型Django-MPTT
- 洛谷P1038神经网络题解
- Django 创建一个应用程序
- 判断闰年的Java算法
- 【洛谷P2696】慈善的约瑟夫
- [ASP.NET]关于DOT NET的IIS配置LocalHost访问和127.0.0.1访问的区别
- 解决linux安装软件依赖的曲线救国方案
- 使用JS获取上一页的url地址
- 使用清华大学开源软件镜像AOSP的“每月更新初始化包”更新指定版本的Android源码
- D01——C语言基础学PYTHON
热门文章
- 个人笔记 - Word2013 论文格式调整
- (转)Git 提交的正确姿势:Commit message 编写指南
- c#网络通信框架networkcomms内核解析之一 消息传送
- 2015 ACM-ICPC 亚洲区上海站 A - An Easy Physics Problem (计算几何)
- 导数与偏导数 Derivative and Partial Derivative
- 基于MFC的Media Player播放器的制作(2---导入第三方库和介绍第三方库)
- firefox error downloading
- vue自定义指令clickoutside实现点击其他元素才会触发
- shell编程:字符串处理方式
- docker-compose的scale的用法