函数

定义和声明

#include<iostream>
int add(int, int); //声明函数
int main(){
    int a = 6, b = 9;
    int c = add(a, b);
    std::cout << c << std::endl;
    getchar();
    return 0;
}
//定义函数
int add(int a , int b)
{
    int c = a + b;
    return c;
}

函数参数

int func(int val) //副本传递
//副本传递时,修改val不影响原来的val值

int func(int &val) //引用传递
int func(int *val) //指针传递
//指针和引用传递时,修改val会影响原来的val值

int func(int a, int b, int args ...);//可变参数
#实例 数字交换
#include<iostream>
void func1(int, int);
void func2(int &, int &);
void func3(int *, int *);
int main(){
    int a = 6, b = 9;
    func1(a, b);
    std::cout << "func1 ----> a:" << a << " b:"<< b << std::endl; //a,b未交换
    func2(a, b);
    std::cout << "func2 ----> a:" << a << " b:" << b << std::endl; //a,b被交换
    func3(&a, &b);
    std::cout << "func3 ----> a:" << a << " b:" << b << std::endl;//a,b被交换
    getchar();
    return 0;
}
void func1(int a , int b){
    int temp = 0;
    temp = a;
    a = b;
    b = temp;
}
void func2(int &a, int &b) {
    int temp = 0;
    temp = a;
    a = b;
    b = temp;
}
void func3(int *a, int *b) {
    int *temp = 0;
    temp = a;
    a = b;
    b = temp;
}
结果:
func1 ----> a:6 b:9
func2 ----> a:9 b:6
func3 ----> a:9 b:6

函数地址作为函数参数

#include<iostream>
void swap(int &, int &);
void func1(int &, int &, void(*pf)(int &, int &));
int main(){
    int a = 6, b = 9;
    void(*pf)(int &, int &);
    pf = swap;
    (*pf)(a,b);
    std::cout << "a:" << a << " b:" << b << std::endl; //a,b被交换

    int c = 17, d = 29;
    func1(c,d,pf);
    std::cout << "c:" << c << " d:" << d << std::endl; // c,d被交换
    getchar();
    return 0;
}

void func1(int &c,int &d,void (*pf)(int &,int &)) {
    (*pf)(c,d);
}
void swap(int &a, int &b) {
    int temp = 0;
    temp = a;
    a = b;
    b = temp;
}
结果:
a:9 b:6
c:29 d:17

内联函数

常规函数的调用过程
程序执行到”函数指令”代码处时,立即存储”函数指令”代码的内存地址,并将函数参数复制到堆栈,然后跳到函数起点的内存单元((函数的内存地址,非”函数指令”代码地址)执行函数代码,函数执行结束后跳回保存的”函数指令”内存地址处,即跳回到程序执行函数指令的那一行,然后继续执行余下的指令.
内联函数调用过程
程序执行到”函数指令”代码处时,编译器将调用的函数代码替换掉该函数指令,无需再跳转到函数的位置去执行.速度比常规函数调用快,但内存开销大,假设程序有10个地方条用了同一个内联函数,则程序中将包含该内联函数代码的10个副本.

#include <iostream>
using namespace std;
inline int Max(int x, int y){
     return (x > y) ? x : y;
}
int main(){
     std::cout << "Max (20,10):" << Max(20, 10) << std::endl;
     std::cout << "Max (0,200): " << Max(0, 200) << std::endl;
     std::cout << "Max(100,1010): " << Max(100, 1010) << std::endl;
     return 0;
}

结果:
Max (20,10): 20
Max (0,200): 200
Max (100,1010): 1010

函数默认参数

带默认参数的函数 必须从右至左添加默认值

void func(int a,int b,double c = 3.14); //合法
void func(int a,int b = 2,double c); //非法
#调用时具有默认参数的参数可选
func(1,2);
func(1,2,3);

类和对象

声明和定义

person.h 声明类person的头文件
若在类中声明函数暨定义,则函数当作内联函数处理

#include<string>
class person {
public:
    person();
    person(std::string name);
    std::string print_info(std::string name,int year);
    void print_name();
    void print();
    int add(int a,int b){return a + b}//当作内联函数处理
private:
    std::string name;
};

person.cpp 定义类person中的函数和变量

#include "person.h"
#include<iostream>
#include<string>
person::person(){};
person::person(std::string name){
    person::name = name;
}

std::string person::print_info(std::string name, int year){
    std::cout << "your name is " << name << " and your age is " << year << std::endl;
    return "hi " + name;
}

void person::print_name(){
    std::cout << person::name << std::endl;
}

void person::print(){
    std::cout << "hello person " << std::endl;
}

main.cpp 使用person类

#include<iostream>
#include<string>
#include "person.h"
int main(){
    person p1;
    p1.print();

    person p2("kyleson");
    p2.print_name();
    std::string info = p2.print_info("kyleson",19);
    std::cout << info << std::endl;
    getchar();
    return 0;
}
结果:
hello person
kyleson
your name is kyleson and your age is 19
hi kyleson

常量成员函数

Date类中的成员函数(+const)表示函数为只读函数,不能对类Date的成员和状态进行修改

class Date {
    int d, m, y;
public:
    int day() const { return d; }
    int month() const;
};
int Date::month() const {
    return Date::m;
}

mutable成员

mutable修饰的成员仍可被常量成员函数修改

class Date {
    int d, m, y;
public:
    int day() const { return d; }
    int month() const;
private:
    int century;
    mutable int cache;
};

int Date::month() const {
    Date::century = 0;//错误,month()函数不可修改century的值
    Date::cache = 0;
    return Date::m;
}

自引用

class Date {
    int d = 12, m = 6, y =2018;
public:
    Date& add_day(){ d++; };
    Date& add_month(){ m++; };
    Date& add_year() { y++; };
private:
    int cache;
    mutable int modied;
};

int main(){
    Date date;
    date.add_year().add_month().add_day();
    getchar();
    return 0;
}

析构函数

类的析构函数是类的一种特殊的成员函数,在每次删除所创建的对象时执行
析构函数的名称与类的名称完全相同,由波浪号(~)作为其前缀,析构函数不会返回任何值,也不能带有任何参数.析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源.

#include <iostream>
using namespace std;
class Line{
  public:
     Line(); // 构造函数声明
     ~Line(); // 析构函数声明
};
Line::Line(void){
     cout << "Object is being created" << endl;
}
Line::~Line(void){
     cout << "Object is being deleted" << endl;
     }
// 程序的主函数
int main(){
     Line line;
     return 0;
}
结果:
Object is being created
Object is being deleted

友元函数

访问类的 private 和 protected 成员

#include <iostream>
using namespace std;
class Box{
     double width;
     public:
                friend void printWidth(Box box);
             void setWidth(double wid);
};
void Box::setWidth(double wid){
     width = wid;
}
//注意:printWidth() 不是任何类的成员函数
void printWidth(Box box){
     cout << "Width of box : " << box.width << endl;
}
int main(){
    Box box;
    box.setWidth(10.0);
    printWidth(box);
    return 0;
}

this 指针

#include <iostream>
using namespace std;
class Box{
public:
       Box(double length = 2.0){
       length = length;
 }
 int compare(Box box){
       return this-> length > box. length;
 }
private:
      double length; 
};
int main(void){
     Box Box1(3.3); 
     Box Box2(8.5); 
     if(Box1.compare(Box2)){
          cout << "Box2 is smaller than Box1" << endl;
     }else{
         cout << "Box2 is equal to or larger than Box1" << endl;
}
    return 0;
}

指向类的指针

#include <iostream>
using namespace std;
class Box{
public: 
    Box(double h = 2.0){
         height = h;
 }
 double Volume(){
        return length * breadth *height;
 }
private:
       double height; 
};
int main(void){
      Box Box1(3.3); 
      Box *ptrBox; 
      ptrBox = &Box1;
      cout << "Volume of Box1: " << ptrBox->Volume() << endl;
      return 0;
}

类的静态成员

静态成员在类的所有对象中是共享的, 无论创建多少个类的对象,静态成员都只有一个副本

class Box{
    public:
         static int objectCount;
         Box(double h = 2.0){
         height = h;
         objectCount++;
     }
     double Volume(){
         return length * breadth *height;
     }
    private: 
         double height; 
};
int Box::objectCount = 0;
int main(void){
     Box Box1(3.3); 
     Box Box2(8.5); 
     cout << "Total objects: " << Box::objectCount << endl; //objectCount = 2
     return 0;
}

继承

#include <iostream>
using namespace std;
// 基类
class Shape {
  public:
    void setWidth(int w) {
        width = w;
    }
    void setHeight(int h) {
        height = h;
    }
  protected:
    int width;
    int height;
};
// 派生类
class Rectangle : public Shape {
  public:
    int getArea() {
        return (width * height); 
    }
};

int main(void) {
    Rectangle Rect;
    Rect.setWidth(5);
    Rect.setHeight(7);
    cout << "Total area:" << Rect.getArea() << endl;
    getchar();
    return 0;
}

多继承

// 基类
class Shape {...};
class PaintCost {...};
// 多继承
class Rectangle : public Shape, public PaintCost {...};

虚函数和纯虚函数 virtual 修饰符

类中被声明为虚函数的函数在基类中实现也可被派生类重写.
类中被声明为纯虚函数的函数在基类中只能声明,定义纯虚函数是为定义一个接口,必须由派生类实现,且这个类是抽象类,包含纯虚函数的类不能创建对象,只能作为基类.

class Shape {
     //虚函数
     virtual int area(){
       cout << "Parent class area :" << endl;
       return 0;
     }
};
class Rectangle : public Shape {
     //重写的虚函数
     int area(){
        cout << "Rectangle class area :" << endl;
        return (width * height);
     }
};

class Shape {
     //纯虚函数 由派生类实现
     virtual int area() = 0;
};

多态

多个派生类根据需要对基类的虚函数进行了不同的实现,在函数调用时会根据派生类的不同进行相应的调用

#include <iostream> 
using namespace std;
class Shape {
  public:
    virtual void area() {
        cout << "Parent class area :" << endl;
    }
};
class Rectangle : public Shape {
  public:
    void area() {
        cout << "Rectangle class area " << endl;
    }
};
class Triangle : public Shape {
  public:
    void area() {
        cout << "Triangle class area " << endl;
    }
};
int main() {
    Shape *shape;
    Rectangle rec;
    Triangle tri;
    shape = &rec;
    shape->area();
    shape = &tri;
    shape->area();
    getchar();
    return 0;
}
结果:
Rectangle class area 
Triangle class area

运算符重载

class Date {
  public:
    int d = 12, m = 6, y = 2018;
    Date operator+(const Date &a);
    void operator++();
};
Date Date::operator+(const Date & a){
    Date c;
    c.d = this->d + a.d;
    c.m = this->m + a.m;
    c.y = this->y + a.y;
    return c;
}
void Date::operator++(){
    this->y++;
    this->m++;
    this->d++;
}

int main(){
    Date a,b;
    Date c = a + b;
    std::cout << c.y << std::endl;
    Date d;
    ++d;//++d == d.operator++();
    std::cout << d.y;
    getchar();
    return 0;
}

异常处理

//捕获并处理异常
void task_master(){
    try{
        auto result = do_task();
    }catch(some_error){
        //todo 
    }
}
//抛出异常
int do_task(){
    if(...)
        return result;
    else
        throw some_error{};
}

#include <iostream>
using namespace std;

double division(int a, int b){
   if( b == 0 ){
      throw "Division by zero condition!";
   }
   return (a/b);
}

int main (){
   int x = 50;
   int y = 0;
   double z = 0;

   try {
     z = division(x, y);
     cout << z << endl;
   }catch (const char* msg) {
     cerr << msg << endl;
   }

   return 0;
}

C++标准异常

#include <iostream>
#include <exception>
using namespace std;

struct MyException : public exception{
  const char * what() const throw (){
    return "C++ Exception";
  }
};

int main(){
  try{
    throw MyException();
  }catch(MyException& e){
    std::cout << "MyException caught" << std::endl;
    std::cout << e.what() << std::endl;
  }catch(std::exception& e){
    //其他的错误
  }
}

文件输入输出

#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>

int main() {
    std::ifstream fin;
    fin.open("test.txt");
    if(fin.is_open() == false){
        std::cerr << "cant not open the file \n";
        std::exit(EXIT_FAILURE);
    }
    std::string item;
    getline(fin,item);
    while (fin){
        std::cout << item << "\n";
        getline(fin,item);
    }
    std::cout << "done" << "\n";
    fin.close();
    return 0;
}


C++      C++

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!