IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++面向对象高级开发 -> 正文阅读

[C++知识库]C++面向对象高级开发

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;  //指针相连
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cLQCPAWF-1633179472335)(D:/Typora/assets/image-20210616133551432.png)]

继承

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;              //pure virtual
  virtual void error(const std::string& msg);  //impure virtual
  int objectID( ) const;                       // non-virtual
  ...
};
class Rectangle: public Shape { ... };
class Ellipse: public Shape { ... };

Template Method

在这里插入图片描述

继承+复合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zA5OjUlR-1633179472339)(D:/Typora/assets/image-20210616163103724.png)]

委托+继承

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uWdn5JUN-1633179472340)(D:/Typora/assets/image-20210616164353909.png)]

Composite

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7NnfFb7g-1633179472340)(D:/Typora/assets/image-20210616201445780.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tqQEFdKr-1633179472341)(D:/Typora/assets/image-20210616201934853.png)]

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-03 16:54:12  更:2021-10-03 16:55:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 21:04:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码