C++面向对象高级开发
一、头文件与类的声明
Object Based(基于对象) vs Object Oriented(面向对象)
Object Based: 面向的是单一的class的设计
object Orited: 面对的是多重classes的设计
Output, C++ vs. C
C++
#include <iostream.h>
using namespace std;
int main()
{
int i=7;
cout<< "im" <<i <<end1;
return 0;
}
C
#include <stdio.h>
int main()
{
int i=7;
printf("i=%d \n",i)
return 0;
}
Header(头文件)中的防卫式声明
complex.h
#ifndef _COMPLEX_
#define _COMPLEX_
#include<>
// 前置声明
class ostream;
class complex;
complex&
_doap1 (complex* ths,const complex& r);
// 类——声明
class complex
{
...
}
//类定义
complex::function ...
#endif
构造函数
inline函数
函数若在class body内定义完成或者在函数定义前加上liline,便自动成为inline 候选人,但是函数太复杂就不会成为inline。最后结果由编译器决定
class complex
{
public:
...
double real () const { return re; } //liline函数候选人
...
}
inline double
imag(constcomplex& x) //liline函数候选人
{
return x.imag();
}
access level (访问级别)
class complex
{
public:(公共)
private:(私有)
private中的数据只能通过publish内的函数读取。
}
构造函数
class complex
{
public:
// 与类同名的是构造函数
complex (double r=0,double i=0) //默认实参
: re(r),im(r) //初始列,初始值 只有构造函数可以用 建议用
{...}
complex (): re(0) ,im(0) //上面的构造函数已经有默认实参了,这个重复了。
private:
double re,im;
}
不带指针的类,基本不用写析构函数
构造函数有很多个overloading(重载)
构造函数放在private中
// Singleton
class A{
public:
A& genInstance();
setup() {...}
private:
A();
A(const A& rsh);
...
}
A& A::genInstance()
{
static A a;
return a;
}
// 用户使用这个类的唯一途径
A::genInstance().setup();
const member functions (常量成员函数)
class complex
{
public:
// 与类同名的是构造函数
complex (double r=0,double i=0)
: re(r),im(r)
{...}
complex& operator +=(const complex&); //为了防止每次传输的值的类型不一样,建议传指针
//输入的const
double real() const{ return re;}
double imag() const{ return im;} //不改变值的时候加const 返回的const
private:
double re,im;
friend complex& ——doapl (comple* ,const complex;) //友元
//同一个class的各个objects个互为友元
}
opertor over
opertor over(操作符重载之一,成员函数) 有this
inline complex&
complex::operator += (this,constcomplex& r) //this是隐藏的指针,写代码不用写
{
return _doapl(this ,r); //this不用声明,可以直接用
}
inline complex& //返回引用,传递者无需知道接收者的形式
_doapl(complex* ths ,const complex& r)
{
ths-> re += r.re;
ths-> im += r.re;
return *ths;
}
c2+=c1; //这里c2就是this指针
opertor over(操作符重载之一,非成员函数) 无this
inline complex //因为返回的是一定是对象,所以返回值
operator + (const complex& x, const complex& y)
{
return complex (real (x) + real (y), imag (x) + imag (y));
// typename() 临时对象
}
inline complex
operator + (const complex& x, double y)
{
return complex (real (x) + y, imag (x));
}
inline complex
operator + (double x, const complex& y)
{
return complex (x + real (y), imag (y));
}
//函数重载,正的意思
inline complex
operator + (const complex& x)
{
return x;
}
三大函数:拷贝构造,拷贝复制,析构
String s1();
String s3(s1); //拷贝构造
s3=s3; //拷贝复制
//class带指针,不要用系统默认的拷贝构造和拷贝复制
class String
{
public:
String(const char* cstr=0);
String(const String& str); //拷贝构造
String& operator=(const String& str); //拷贝赋值
//避免指针指向同一个地方,从而没有新的对象产生,并且会导致内存泄漏
~String(); //析构函数
char* get_c_str() const { return m_data; }
private:
char* m_data;
};
inline
String::String(const char* cstr)
{
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
String& String::operator=(const String& str)
{
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;
}
堆、栈与 内存管理
stack objects的生命期
class Complex{...};
...
Complex c3(1,2);
{
Complex c1(1,2);
static Complex c2(1,2);
}
c1:在作用域结束后就会被自动清理
c2:在作用域结束后还会存在
c3: 全局存在
heap objeces的生命期
class Complex{...};
...
{
Complex* p =new Complex;
...
delete p;
}
p所指的便是heap object,其生命在它被deleted之后结束。
class Complex {...};
...
{
Complex* p = new Complex;
}
以上出现内存泄漏(memory leak),因为当作用域结束,p所指的heap object仍然存在,但指针p的生命周期缺结束了,作用域之外再也看不到p,删除不了p了。
扩展补充:类模板,函数模板,及其他
static
class Account{
public:
static double m_rate;
static void set_rate(const double& x){m_rate = x};
};
double Account::m_rate =8.0;//静态变量必须写这行
int main()
{
Account::set_rate(5.0)
Account a;
a.set_rate(7.0);
}
把ctors放在private中
// Singleton
class A{
public:
static A& genInstance();
setup() {...}
private:
A();
A(const A& rsh);
...
}
A& A::genInstance()
{
static A a;
return a;
}
// 用户使用这个类的唯一途径
A::genInstance().setup();
class template类模板
template<typename T>
class complex
{
public:
complex (T r=0,T i=0)
:re(r),im(i)
{ }
complex& operator += (const complex&);
T real () const {return re;}
T imag () const {return im;}
private:
T re,im;
friend complex& _doapl (complex*,const complex&);
};
{
complex<double> c1(2.5,1.5);
complex<int> c2(2,6);
}
namespace
namespace std
{
...
}
//三种使用方法
1.using namespace std;
2.using std::cout;
3.std::cin<<;
继承、复合、委托
复合
template <class T,class Sequence = deque<T> >
class queue{
...
protected:
Sequence c;
}
//换一种方式
template <class T>
class queue {
...
protected:
deque<T> c;
}
//也就是说在类queue中有类deque;
构造由内而外
析构由外而内
委托
class StringRep
class String{
public:
private:
StringRep* rep; //指针相连
}
继承
struct _List_node_base
{
_List_node_base* _M_next;
_List_node_base* _M_prev;
};
template<typename _Tp>
struct _List_node
: public _List_node_base //继承
{
_Tp _M_data;
};
继承和虚函数
- non-virtual函数:你不希望derived class重新定义它
- virtual 函数:你希望derived class重新定义它,且你对它已有默认的定义
- pure virtual 函数 :derived class一定要重新定义它,你对它没有默认定义
class Shape {
public:
virtual void draw( ) const = 0;
virtual void error(const std::string& msg);
int objectID( ) const;
...
};
class Rectangle: public Shape { ... };
class Ellipse: public Shape { ... };
Template Method
继承+复合
委托+继承
class Subject
{
int m_value;
vector<Observer*> m_views;
public:
void attach(Observer* obs) {
m_views.push_back(obs);
}
void set_val(int value)
{
m_value = value;
notify();
}
void notify()
{
for (int i = 0; i < m_views.size(); ++i)
m_views[i]->update(this, m_value);
}
};
class Observer
{
public:
virtual void update(Subject* sub, int value) = 0;
};
Composite
class Component
{
int value;
public:
Component(int val) { value = val; }
virtual void add( Component* ) { }
};
class Composite: public Component
{
vector <Component*> c;
public:
Composite(int val): Component(val) { }
void add(Component* elem) {
c.push_back(elem);
}
…
};
class Primitive: public Component
{
public:
Primitive(int val): Component(val) {}
};
Prototype
|