- Brief: C++ 面向对象高级开发笔记记录
- Author: Dargon
- Note date: 2021/03/01
- Source: B站 侯捷 C++面向对象高级开发 教程
文章目录
1 关于C++class语法注意点
01 private
- private里面 放的是自己所使用的data member,所以里面的数据只给自己人 使用,外界其它使用的 函数或者其它的 放在 public里面
02 constructor 构造函数
-
当你作为设计者 设计一个class 的时候,在外面供别人使用的时候,会有初始化这个Class的操作,
这里有别C语言的操作 你可以设计不止一种的初始化的方式
注重使用的是一种叫做 initialization list 的初始化方式 比较好的一种 就是带有 : 符号 -
符号后面的list 是一种列表初始化的方式
-
class的用法 就相当int, float , double的用法
03 pass by reference & 是一个好符号 效率高
- 当我们像函数的参数传递的时候 可以 pass by value or reference,如果是一个value的话 例如double 就要占用4字节的大小 若是reference 像是一个指针的形式传递进来的,效率会有提升
- 传递参数 和 返回参数 return 都是类似 要有思考
04 const
- 可以 设计成const 的就需要const 类型 因为 non-const 类型的函数 不能使用或者表达 const的 东西,从使用你的class 的客户来说 他们并不知道你这里是non-const的 尽量使用const 在可以的情况下。
05 operator的 overloading
- C++ 设计者说: 你不用设计plus 来体现+ 了 我允许你来设计自己的operator ,你可以加任和东西 两个数 两个人 两个石头 哈哈哈哈 只要你能设计出来
- 在操作者进行 连串使用的 操作符的时候 返回类型 就要小心了!
- temp object 临时对象 typename()操作 用完就没有了 在比如 C1 + C2的时候 里面return的东西 没有名字 就是temp object,也就是 你只有 在C =C1+C2 才能保存下 这个临时值 相当于 C 的赋值了 如C语言中的 int()
- 可以看到 成员函数的定义 在class body 外的话 需要有class scope :: 符号的,
- 在重载 + 操作符的时候 ,没有设置为class 的member function,是因为不只是 使用 complex + complex ,我们 其他的地方还有使用 ,在定义非 member function的时候 就不需要 有class scope ::和class name 做限制了。
2 关于带有指针的class 设计问题
01 constructor 构造函数 和destructor析构函数
- 俗称Big Three (copy ctor 构造 ,copy op赋值, 析构)侯老师说( 不知道西方文化中 Big Three 有什么特殊的含义或者是谚语意义 哈哈哈哈 )下面是带有指针函数的class body 里面的构造函数
class String {
public:
/* 俗称 Big Three */
String( const char* cstr =0 ); /* default constructor */
String( const String& str ); /* copy constructor deep copy*/
String & operator =( const String& str );
~String(); /* destructor function */
char* get_c_str() const { return m_data; }
private:
char * m_data; /* data member */
};
- public 里面的member function 默认为 inline 函数 内联函数
- 构造函数的细节 你new 用【】申请内存 就要delete 的时候 用delete【】 来释放内存
inline String::String( const char* cstr =0 ) {
if( cstr ) {
m_data =new char[ strlen( cstr ) +1 ];
strcpy( m_data, cstr );
}
else {
m_data =new char[1];
* m_data ='\0'; /* 只申请一个结束字符 */
}
}
inline String::~String() {
delete[] m_data;
}
- inline 作用 使我们
建议
编译器 设置为inline 只是建议 最终的决定权是在 编译器本身 - 春天来了 韭菜的成熟 也变得提前了 割韭菜去
02 copy constructor
- 默认的copy 是copy 的一份指针过来 这时候 就变成两个指针 共同指向一块相同的内存,当通过一个指针改变这块内存内容的话,另一个也会收到影响,所以解决办法就是 利用copy 构造出另一块内存(new) 去容纳这个 蓝本 ,这样两块就变的互不影响
inline String::String( const String& str ) {
m_data =new char[ strlen( str.m_data ) +1 ]; /* allocate new memory block */
strcpy( m_data, str.m_data );
}
03 copy assignment operator
inline String& String::operator=( const String& str ) {
/* self assignment */
if( this ==&str ) {
return *this;
}
delete[] m_data;
m_data =new char[ strlen( str.m_data ) +1 ];
strcpy( m_data, str.m_data );
return *this;
}
- 利用 b =a; 先把 左边b 的m_data 删除掉 ,再深度赋值 右边的m_data 到 左边的 m_data 再返回
- self assignment 是非常必要的 当同时 指向同一块 memory block的时候,没有自我检测的话 这一块东西 会被delete 就意味着 唯一的一块数据 被删除了 下面再去访问的话 就应该出错。
04 所谓 stack(栈)所谓 heap(堆)
- 平时在所调用的函数里面 创建的一块内存空间 memory space,函数本身会形成一个stack 用来放置参数,当用完之后 自动删除
- 在heap里面 是由 new 来申请出来的一块空间 你用完之后 需要自己手动删除它
- static 和 global的生命力作用域都是很长的 普通的作用域结束 不影响他们的声明周期 就是硬朗 到整个程序结束之后 才会跟着消失。
- 前面有 array【】 去申请(new)内存的话,你后面需要在释放的时候 利用delete【】 (array delete)去释放 这样才能一一对应着
05 static 补充
- non-static 数据/函数里面可以去使用 this 这个东西 ,而static 没有这个 只能处理static 的数据或者东西
- 在类中有 static 数据的情况下 使用之前 需要在外部进行一个 声明(赋予它初值 这是一个很重要的点 自己在这里入坑一次)