C
1972C++
1983new C
-> C with Class
-> C++
- 语言没有关键字,数据必须是全局的
C++语言
C++,关于数据和函数
- 不同平台的文件的命名不同.h
, .hpp
, .cpp
- 标准库include <iostream.h>
- 非标准库include "complex.h"
cout
方式输出数据来调试printf
必须明确数据的类型.h
文件的顺序。class template介绍
T
根据不同的定义<double>
或<int>
来重新定义inline 内联函数
访问级别(数据在private是好习惯)
构造函数(不带指针)
: re(r), im(i)
的写法,这种写法表示初始化,不同于赋值。complex c1(2,1)
,调用构造函数,直接复制r=2, i=1
complex c2
,调用构造函数,默认参数
complex * p = new complex(4)
,调用构造函数,得到指针。疑问???
构造函数的overloading(重载)
real
取得实部或设定实部,编译时有所不同(如右下角所示)。注意不添加constcomplex () : re(0), im(0) {}
构造函数重构是不行的。构造函数放在private位置
构造函数的设计模式
getInstance
(名称随意)来取得内部函数const member functions(常量成员函数),设计更好的函数
const
,在real()
和imag()
之后,只是将数据取出来const
,但使用者调用const complex c1(2,1)
,说明函数不改变数据,则与构造函数冲突。参数选择pass by value or pass by reference (to const)(传reference是好习惯)
const complex&
传递到const
,传递过去但不修改数值ostream& os
传递到非const
,传递过去,修改数值c2 += c1
传递的是引用ostream& os, const complex& x
,第一步分是非const
,第二部分是const
返回值传递returen by value or by reference (to const)
complex&
返回值传递的是referencefriend友元
complex& __doapl (..)
是frinedths
直接读取re
和im
同一个class的各个object互为友元
int func(..)
目的是计算实部虚部之和,直接读取re
和im
。c2.func(c1)
,用c2的函数来处理复数c1class body外的各种定义
complex* ths
的数值会被改动const complex& r
的数值不会被改动operator overloading 操作符重载之一,成员函数
this
,调用者c2
就是this
,编译器会把c2
地址传递过去c1
就是r
this
,但可以在里面直接使用_doapl
,do assignment plus,标准库的代码return by reference
return *ths
,返回的是object,但声明指的是complex&
,是引用。二者可以搭配使用*
指返回的value,传递者无需知道接收端用reference形式来接收c1
是value,用complex& r
来接收c3 += c2 += c1
的使用,则重载函数的返回值必须明确complex&
,而不能使用void
class body之外的重定义
const complex& x
非成员函数的操作符重载
+
也许找成员函数,也许找非成员函数,但不能重复temp object临时对象
+
运算,还没有执行=
,所以运算的结果在执行+
运算时,其实不知道要传递给谁+=
运算,在执行+=
时,已经知道运算结果是要赋值给左侧的变量,因此可以传referencetypename()
的语法,创建临时对象 complex()
得到(0,0),complex(4,5)
得到(4,5),这两个执行完,内容就消失了。+
和-
的使用需要明确是加减还是正负特殊的操作符,必须写成全局函数
cout
是对象,其class name是ostream
,传递引用ostream& os
,但不可以用const
,因为添加之后,os
不可以改变,这与实际不符。因为每次执行<<
,os
都在改变,所以不能添加const
。
函数设计:考虑是否用引用,是否用const
void
,否则则不能使用连续<<
#ifndef __MYSTRING__
#define __MYSTRING__
...
#endif
Step 3: 书写哪些函数
const
double real() const { return re;}
double image() const {return im;}
const after a function declaration means that the function is not allowed to change any class members (except ones that are marked mutable). So this use of const only makes sense, and is hence only allowed, for member functions. (http://stackoverflow.com/questions/3141087/what-is-meant-with-const-at-end-of-function-declaration)
Step 4: 本体之外的函数
操作符重载
inline complex&
complex::operator += (const complex& r)
{
return _doapl (this, r)
}
const complex & r
,r
<-> right字符串用指针,因为不确定字符串的长短
char*
指向字符构造函数
\0
new char[1]
并添加结束符\0
strlen(cstr)+1
,在给复制。之后进行数据的拷贝。delete[] m_data
{...}
作用域里面
String* p = new String("hello");
delete p;
拷贝构造函数
如果没有自己写的copy函数,会出现泄露。(浅拷贝)
深拷贝
String s2(s1);
就是对拷贝构造函数的调用String s2=s1;
与上一句话含义完全相同,因为s2
没有,所以需要重新创造,再完成复制。拷贝赋值函数
delete[] m_data
m_data = new char {strlen(str.m_data) +1];
strcpy(m_data, str.m_data)
output函数
stack
new
来动态从heap
中取得,new Complex(3)
,初值是3,动态(dynamic allocated)得到内存,动态获得就意味着必须delete
new
与delete
搭配使用 Complex* pc = new Complex(1,2)
,里面的new函数分解为三个动作。定义一个指向Complex
的指针。
operator new
函数来完成。
operator new
operator new
函数,进一步调用malloc(n)
函数sizeof(Complex)
完成Complex
类的设计由实部和虚部两个double完成,因此sizeof(Complex)
的结果=8.operator new
反馈的结果是指向void
的指针。Complex::Complex
,函数名称与类相同的函数。
pc
调用的Comple::Complex
函数,因此this
就是pc
。而pc
就是两个doulbe
的起始位置。delete
是new
的反作用。delete pc
主要转化为两个动作
String
而言,会执行两次delete00000041
= 64的十六进制40 + 最后一位(1:系统给出去,0:没给出去)pad
的占位符3
,用一个整数记录。delete []
,即array delete,执行三次
?!
的位置delete
直接删除,因为内部没有再次动态分配。原文:http://www.cnblogs.com/kongww/p/5249283.html