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;
}

涉及资源管理的操作:构造、赋值、析构、交换(适合指针)

最新文章

  1. Java基础学习--抽象类与抽象函数
  2. 开发人员必读openstack网络基础
  3. 关于VR边纹理材质的渲染
  4. java运算符总结
  5. Eclipse c++环境搭建 并加载OpenCV库 2015最新
  6. # 36氪开放日 • 杭州 • 11月10日 # 谈谈参会感受
  7. [转]在ITunes播放中前进、后退五秒的快捷键
  8. JAVA 初识类加载机制 第13节
  9. PHP常用数组(Array)函数整理
  10. jQuery中的自定义插件之----工厂方法(Factory Widget)
  11. 树形结构模型Django-MPTT
  12. 洛谷P1038神经网络题解
  13. Django 创建一个应用程序
  14. 判断闰年的Java算法
  15. 【洛谷P2696】慈善的约瑟夫
  16. [ASP.NET]关于DOT NET的IIS配置LocalHost访问和127.0.0.1访问的区别
  17. 解决linux安装软件依赖的曲线救国方案
  18. 使用JS获取上一页的url地址
  19. 使用清华大学开源软件镜像AOSP的“每月更新初始化包”更新指定版本的Android源码
  20. D01——C语言基础学PYTHON

热门文章

  1. 个人笔记 - Word2013 论文格式调整
  2. (转)Git 提交的正确姿势:Commit message 编写指南
  3. c#网络通信框架networkcomms内核解析之一 消息传送
  4. 2015 ACM-ICPC 亚洲区上海站 A - An Easy Physics Problem (计算几何)
  5. 导数与偏导数 Derivative and Partial Derivative
  6. 基于MFC的Media Player播放器的制作(2---导入第三方库和介绍第三方库)
  7. firefox error downloading
  8. vue自定义指令clickoutside实现点击其他元素才会触发
  9. shell编程:字符串处理方式
  10. docker-compose的scale的用法