第1章 C++编程技术

/*

  第一篇 预备知识
  第1章 C++编程技术
   1.1 类和对象
   1.2 类的继承
   1.3 函数重载
   1.4 访问控制
   1.5 操作符重载
   1.6 显式类型转换
   1.7 异常处理
   1.8 名字空间
   1.9 友员函数
   1.10 内联函数
   1.11 静态成员
   1.12 本章小结

*/

//  第一篇 预备知识
//  第1章 C++编程技术
//   1.1 类和对象 ------------------------------------------------------------------------------------------------------
// 晕,提供代码居然与书里的对不上的!自己输。

// p4
#include <iostream>
using namespace std;

//Compute.h文件
//因为是单文件调试,所以把头文件放到这里了
class CCompute{
  protected:
    int i;
    int j;
  public:
    CCompute(int a,int b){
      i=a;
      j=b;
    }
    ~CCompute(){}
    int sum();
    int minus();
};

int CCompute::sum(){
  return i+j;
}
int CCompute::minus(){
  return i-j;
}

int main(){
  CCompute computeObj(3,8);
  cout << "The sum is: " << computeObj.sum() << endl;
  cout << "The minus is: " << computeObj.minus() << endl;

  CCompute *pComputeObj=new CCompute(2,5);
  cout << "The sum is: " << pComputeObj->sum() << endl;
  cout << "The minus is: " << pComputeObj->minus() << endl;  

  return 0;
}

//   1.2 类的继承 ------------------------------------------------------------------------------------------------------

// p5
#include <iostream>
using namespace std;

//Compute.h文件
//因为是单文件调试,所以把头文件放到这里了
class CCompute{
  protected:
    int i;
    int j;
  public:
    CCompute(int a,int b){
      i=a;
      j=b;
    }
    ~CCompute(){}
    int sum();
    int minus();
};

int CCompute::sum(){
  return i+j;
}
int CCompute::minus(){
  return i-j;
}

// 继承类
class CCompute2:public CCompute{
  public:
    CCompute2(int a,int b):CCompute(a,b){} // 调用基类构造函数
    int mul(); // 添加自己的乘法函数
};
int CCompute2::mul(){
  return i*j;
}

int main(){
  CCompute2 compute2Obj(6,5);
  cout << "The mul is: " << compute2Obj.mul() << endl;

  return 0;
}

//   1.3 函数重载 ------------------------------------------------------------------------------------------------------

#include <iostream>
using namespace std;

// 基类
class CBase{
  public:
    virtual void f(int x){ // 虚函数
      cout << "CBase::f " << x << endl;
    }
    void g(float x){ // 木有 virtual
      cout << "CBase::g " << x << endl;
    }
  };

// 继承类
class CDerived:public CBase{
  public:
    void f(int x){
      cout << "CDerived::f " << x << endl;
    }
    void g(float x){
      cout << "CDerived::g " << x << endl;
    }
  };

int main(){
  CDerived DerivedObj;
  DerivedObj.f(3); // 继承类的f函数
  DerivedObj.g(6.0f); // 继承类的g函数
  //
  CBase *pBaseObj=&DerivedObj;
  pBaseObj->f(3); // 因为virtual了,执行继承类的f函数
  pBaseObj->g(6.0f); // 因为木有virtual,执行的是基类的g函数

  return 0;
}

//   1.4 访问控制 ------------------------------------------------------------------------------------------------------

//   1.5 操作符重载 ------------------------------------------------------------------------------------------------------

// p9
#include <iostream>
using namespace std;

class Complex{
  private:
    double real; // 实数部分
    double image; // 虚数部分
  public:
    Complex(){}
    Complex(double a, double b){
      real=a;
      image=b;
    }
    Complex operator+(Complex &c){
      Complex tmp; // 因为要返回对象
      tmp.real=c.real+real;
      tmp.image=c.image+image;
      return tmp;
    }
    Complex operator++(){ // 前缀++ 如++i
      real+=1;
      image+=1;
      return *this;
    }
    Complex operator++(int) { // 后缀++,如i++ 。int后不需要参数名,反正用不着。不过写上也木事
      real+=10; // just for test,故意加10
      image+=10;
      return *this;
    }
    void print(){
      cout << real << "  " << image << endl;
    }
  };

int main(){
  Complex c1(3.6, 7.2);
  Complex c2(10.1, 20.3);
  Complex c3=c1+c2; // 调用 operator+
  c3.print();
  Complex c4=c1.operator+(c2);
  c4.print(); // 效果一样咯
  ++c3; // 调用 operator++
  c3.print();
  c4++; // 调用 operator++(int)
  c4.print();

  return 0;
}

//   1.6 显式类型转换 ------------------------------------------------------------------------------------------------------

// p10
#include <iostream>
using namespace std;

int main(){
  double d(3.2);
  int i=static_cast<int>(d);
  cout << i << endl;

  return 0;
}

// reinterpret_cast
#include <iostream>
using namespace std;

int main(){
  double d(9.3);
  double *pd=&d;
  int *pi=reinterpret_cast<int*>(pd);
  cout << *pi << endl;
  cout << pd << "  " << pi << endl; // 本身地址木有变,变的是指向类型。。

  class A{};
  class B{};
  A* pa=new A;
  B* pb=reinterpret_cast<B*>(pa);

  long j=reinterpret_cast<long>(pi); // 把地址转换成了数
  cout << j << endl;

  return 0;
}

// const_cast
// p10-11
#include <iostream>
using namespace std;

int main(){
  int i(3);
  const int *pci=&i;
  cout << ++i << endl; // 变量i本身可以改变。这里成4
  // cout << ++(*pci) << endl; // error,常量指针指向的变量不能改变
  int *pj=const_cast<int*>(pci); // 去除了指针变量的常量属性
  cout << ++(*pj) << endl; // 所以这样就可以了,i成5

  class A{};
  const A* pca=new A;
  A *pa = const_cast<A*>(pca);
  cout << pa << endl;

  const int k(4);
  //int j=const_cast<int>(k); // error,想去除变量k的常数属性,不可以

  //const int cj=const_cast<const int>(i); // 非指针转换,不可以
  const int ck=(const int)i; // 隐式转换,可以
  //++ck; // 改变常量ck,不可以

  return 0;
}

// static_cast
// p11
#include <iostream>
using namespace std;

int main(){
  int i(0);
  double d=static_cast<double>(i);
  int j=static_cast<int>(d);

  class Base{};
  class Derived:public Base{};
  Derived d2;
  Base b=static_cast<Base>(d2); // Base b=(Base)d;

  // 继承类指针转换为基类指针,具有一定的危害性
  Derived *pd=new Derived;
  Base *pb=static_cast<Base*>(pd);
  Base *pc=new Base;
  Derived *pe=static_cast<Derived*>(pc);

  return 0;
}

// dynamic_cast
//略

//   1.7 异常处理 ------------------------------------------------------------------------------------------------------

// p14 guide中中文输出不正常,可在VC6中调试
#include <stdio.h>
int main(void)
{
  try
  {
    printf("try块1代码执行\n");
    throw 10; // 因为抛出的是整数
  }
  catch(int &i) // 所以这里被捕捉到了
  {
    printf("处理try块1的int类型异常对象,值为%d\n", i);
  }
  catch(double d)
  {
    printf("处理try块1的double类型异常对象,值为%f\n", d);
  }
  //
  try
  {
    printf("try块2代码执行\n");
    throw 23.8;
  }
  catch(int &i)
  {
    printf("处理try块2的int类型异常对象,值为%d\n", i);
  }
  catch(double d)
  {
    printf("处理try块2的double类型异常对象,值为%f\n", d);
  }
  //
  printf("程序结束\n");
  return 0;
}

// p15
#include <stdio.h>
int main(void)
{
  try
  {
    int a = 0;
    int b = 32 / a;
  }
  catch(...)
  {
    //所有异常
    printf("异常发生\n");
  }
  return 0;
}

// p15
#include <stdio.h>
class A
{
  public:
    void f()
    {
        printf("函数f打印\n");
    } void g()
    {
        throw 12;
    }
};
int main(void)
{
  A a;
  a.f(); //调用f
  try
  {
    a.g(); //调用g
  }
  catch(int &i)
  {
    printf("调用函数g出现运行异常,值为%d\n", i);
  }
  return 0;
}

// 后略

//   1.8 名字空间 ------------------------------------------------------------------------------------------------------

// p18
#include <stdio.h>
namespace NS1
{
  int a = 1;
}

namespace NS2
{
  int a = 8;
}

int main(void)
{
  printf("NS1名字空间定义的a值为%d\n", NS1::a); //打印a=1
  printf("NS2名字空间定义的a值为%d\n", NS2::a); //打印a=8
  return 0;
}

// p19
#include <stdio.h>
namespace Myspace
{
  int i = 1;
  int j = 3;
}
int main(void)
{
  using namespace Myspace;
  i = j + 10;
  j = 20;
  printf("Myspace定义的变量i的值为%d\n", i); //打印13
  printf("Myspace定义的变量j的值为%d\n", j); //打印20
  return 0;
}

//   1.9 友员函数 ------------------------------------------------------------------------------------------------------

#include <stdio.h>
class B;
class A
{
    bool bfinish;
    friend bool check(A a, B b); //声明check为类A的友员函数
  public:
    A(bool b)
    {
        bfinish = true;
    }
};
class B
{
    bool bfinish;
    friend bool check(A a, B b); //声明check为类B的友员函数
  public:
    B(bool b)
    {
        bfinish = b;
    }
};
bool check(A a, B b)
{
  //定义友员函数
  if(a.bfinish && b.bfinish)
    return true;
  else
    return false;
}
int main(void)
{
  A a(true);
  B b(false);
  if(check(a, b))
    printf("bfinish都是true\n");
  //调用友员函数
  else
    printf("bfinish不都是true\n");
  return 0;
}

// p21
#include <stdio.h>
class B;
class A
{
    int i;
  public:
    A(int i_)
    {
        i = i_;
    }
    friend bool operator > (A &a, B &b);
};
class B
{
    double d;
  public:
    B(double d_)
    {
        d = d_;
    }
    friend bool operator > (A &a, B &b);
};
bool operator > (A &a, B &b)
{
  return a.i > b.d;
}
int main(void)
{
  A a(19);
  B b(13.2);
  if(a > b)
    printf("a>b \n");
  else
    printf("a<=b \n");
  return 0;
}

//   1.10 内联函数 ------------------------------------------------------------------------------------------------------

// p22
#include <stdio.h>
class A
{
    int i;
  public:
    A(int i_)
    {
        i = i_;
    }  //构造函数定义为内联函数
    void print();
};
inline void A::print()
{
  //print函数定义为内联函数
  printf("i的值为%d\n", i);
}

int main(void)
{
  A a(3);
  a.print();
  return 0;
}

//   1.11 静态成员 ------------------------------------------------------------------------------------------------------

// p22-23
#include <stdio.h>
class A
{
    static int i; //声明为静态变量
    static int j;
    int k;
  public:
    A(int k_)
    {
        k = k_;
    }
    static void setj(int j_);
    static void print_static();
    void print();
};
int A::i = 10; //直接定义静态成员变量
int A::j; //必须先定义,再用函数初始化
void A::setj(int j_)
{
  j = j_;
}
void A::print_static()
{
  printf("静态成员变量i和j值为%d和%d\n", i, j);
}
void A::print()
{
  printf("成员变量k的值为%d\n", k);
}
int main(void)
{
  A::setj(20);
  A a(3);
  A::print_static(); //也可使用a.print_static()形式
  a.print();
  return 0;
}

//   1.12 本章小结

TOP

时间: 2024-10-05 16:46:52

第1章 C++编程技术的相关文章

Delphi知识点与技术概述【第一章Delphi编程】

Delphi的基本特性:语言,运行时库(RTL),核心类库 语言特性: Delphi 即是一门语言同时又是一个开发工具.它是经典Pascal语言的面向对象的扩展. 内容提要 *类与对象 Delphi中每个可视放置在窗体中的组件是类的类型对象,该类可在系统库中获得.类和对象之间的关系和变量和类型之间的关系相同. *封装:provate public "黑盒子",不需要知道里面有什么,只需要知道怎么样和黑盒子接口. 基本的3个访问标示符private.protected.public.它只

《好学的C++ 第2版》 第9章 一些高级编程技术

转向C++0x和OOP之前,需要掌握其他一些技巧. C++命令行参数: main函数须这样定义: int main(int argc, char* argv[]){/*...*/}  //argc计数包括程序名,所以至少是1:argv[0]就是程序名.这两个参数可以任意使用,但是是只读的,可以随意显示或复制它们.程序中可以通过argc判断输入参数是否足够(例如大于1),通过argv判断各参数是否合法,合法的话存入其他变量使用:不合法的话提示输入后,存入其他变量中使用即可.MAX_PATH:系统能

[CSAPP笔记][第十二章并发编程]

第十二章 并发编程 如果逻辑控制流在时间上是重叠,那么它们就是并发的(concurrent).这种常见的现象称为并发(concurrency). 硬件异常处理程序,进程和Unix信号处理程序都是大家熟悉的例子. 我们主要将并发看做是一种操作系统内核用来运行多个应用程序的机制. 但是,并发不仅仅局限于内核.它也可以在应用程序中扮演重要的角色. 例如 Unix信号处理程序如何允许应用响应异步事件 例如:用户键入ctrl-c 程序访问虚拟存储器的一个未定义的区域 其他情况 访问慢速I/O设备 当一个应

转载--提高C++性能的编程技术

读书笔记:提高C++性能的编程技术 第1章 跟踪范例 1.1 关注点 本章引入的实际问题为:定义一个简单的Trace类,将当前函数名输出到日志文件中.Trace对象会带来一定的开销,因此在默认情况下不会开启Trace功能.问题是:怎么设计Trace类,使得在不开启Trace功能时引入的开销最小. 1.2 使用状态变量开关功能 用宏来开关Trace功能很简单,在不开启时开销完全没有: #ifdef TRACE Trace trace("aaa"); #endif 缺点是每次开关都需要重新

编程技术日新月异,TAOCP经典永驻

1968年,C语言还未出现,鼠标刚刚问世,ARPAnet还在酝酿之中. 2017年,编程语言多达几百种,PC走进千家万户,ARPAnet已经退役十多年. 1968年,有一套关于编程的图书出版了第1卷. 2017年,这套书仍然是科技领域的经典. 这就是<计算机程序设计艺术>. <计算机程序设计艺术>简写为TAOCP. 1962年,编程界先驱高德纳开始写作<计算机程序设计艺术>.他原本只打算写12章,谁知道一写就是几十年,一本书变成了一部"史诗". 19

.NET 线程池编程技术

摘要 深度探索 Microsoft .NET提供的线程池, 揭示什么情况下你需要用线程池以及 .NET框架下的线程池是如何实现的,并告诉你如何去使用线程池. 内容 介绍 .NET中的线程池 线程池中执行的函数 使用定时器 同步对象的执行 异步I/O操作 监视线程池 死锁 有关安全性 结束 介绍 如果你有在任何编程语言下的多线程编程经验的话,你肯定已经非常熟悉一些典型的范例.通常,多线程编程与基于用户界面的应用联系在一起,它们需要在不影响终端用户的情况下,执行一些耗时的操作.取出任何一本参考书,打

Java学习笔记—第十三章 数据库编程入门

第十三章 数据库编程入门 了解JDBC Java中对数据库的访问主要是通过JDBC进行的.JDBC是Java数据库连接技术(Java Database Connectivity)的简称,是用于执行SQL语句的API,可以为多种关系数据库提供统一访问.由一组用Java语言编写的类和接口组成.(SQL是Structure Query Language的缩写,意义为结构化查询语言,是一种标准的关系数据库访问语言.) JDBC的工作机制 使用JDBC完成对数据库的访问主要包括以下五个层次:Java应用程

[CSAPP笔记][第十一章网络编程]

第十一章 网络编程 我们需要理解基本的客户端-服务端编程模型,以及如何编写使用因特网提供的服务的客户端-服务端程序. 最后,我们将把所有这些概念结合起来,开发一个小的但功能齐全的Web服务器,能够为真实的Web浏览器提供静态的和动态的文本和图形内容. 11.1 客户端 - 服务器编程模型 每个网络应用程序都是基于客户端 - 服务器模型的 采用这种模型,一个应用是由一个服务器进程 和一个或多个客户端进程组成. 服务器管理某种资源,并且通过操作这种资源为它的客户端提供某种服务. WEB服务器,代表客

第11章 AWT编程

第11章 AWT编程 AWT全称是抽象窗口工具集 GUI 图形用户界面 AWT缺点 1.图形显示丑陋 2.AWT组件这能使用这些操作系统共有的组件 3.AWT非常笨拙,是非面向对象的编程模式 总体上Swing组件代替了大部分AWT组件,对AWT有很好的补充和加强 Swing仅提供了能力更强大的用户界面组件,即使是完成采用Swing编写的组件也依然要使用AWT的事件处理机制 java.awt包中提供了两个基类表示图形界面元素 Component 和MenuComponent 代表一个能以图形化方式