c++ basic for ioser

原文链接

虚函数

先来看个错误示例:

class Foo {
      public:
    int value() { return 5; }
};

class Bar : public Foo {
      public:
    int value() { return 10; }
};

Bar *b = new Bar();
Foo *f = (Foo*)b;
printf(“%i”, f->value());// Output = 5

期望输出为10,可是输出5;要想使输出为10,就需要用到虚函数,正确示例如下:

class Foo {
      public:
    virtual int value() { return 5; }
};

class Bar : public Foo {
      public:
    virtual int value() { return 10; }
};

构造函数

class Foo {
      private:
        int x;

      public:
        Foo() {
            x = 0;
           }

        Foo(int x) {
            this->x = x;
        }
};

对于成员变量的初始化,还有种写法:

class Foo {
      private:
        int x;

      public:
        Foo() : x(0) {}

        Foo(int x) : x(x) {}
};

调用父类构造函数示例:
class Foo {
private:
int x;

  public:
    Foo() : x(0) {
    }

    Foo(int x) : x(x) {
    }
};

class Bar : public Foo {
  private:
    int y;

  public:
    Bar() : Foo(), y(0) {
    }

    Bar(int x) : Foo(x), y(0) {
    }

    Bar(int x, int y) : Foo(x), y(y) {
    }
};

c++11新引入:某个构造函数调用同一个类里另一个构造函数。其局限性在于:成员变量的初始化只能放在函数体内,不能跟在冒号后。示例如下:

class Bar : public Foo {
  private:
    int y;

  public:
    Bar() : Foo() {
        // Perform common initialisation
    }

    Bar(int y) : Bar() {
        this->y = y;
    }
};

析构函数

析构函数大多都是虚函数(除非这个类你不需要继承它),会自动调用父类的析构函数,示例如下:

class Foo {
  public:
    virtual ~Foo() {
        printf(“Foo destructor\n”);
    }
};

class Bar : public Foo {
  public:
    virtual ~Bar() {
        printf(“Bar destructor\n”);
    }
};

Bar *b = new Bar();
Foo *f = (Foo*)b;
delete f;
// Output:
// Bar destructor
// Foo destructor

操作符重载

详见

class DoubleInt {
  private:
    int x;
    int y;

  public:
    DoubleInt(int x, int y) : x(x), y(y) {}

    DoubleInt operator+(const DoubleInt &rhs) {
        return DoubleInt(x + rhs.x, y + rhs.y);
    }

    DoubleInt operator+(const int &rhs) {
        return DoubleInt(x + rhs, y + rhs);
    }
};


DoubleInt a(1, 2);
DoubleInt b(3, 4);
DoubleInt c = a + b;

DoubleInt a(1, 2);
DoubleInt b = a + 10;// b = DoubleInt(11, 12);

模板函数

模板函数只能在头文件中定义实现,示例如下:

template <typename T>
void swap(T a, T b) {
    T temp = a;
    a = b;
    b = temp;
}


int ix = 1, iy = 2;
swap(ix, iy);

float fx = 3.141, iy = 2.901;
swap(fx, fy);

Person px(“Matt Galloway”), py(“Ray Wenderlich”);
swap(px, py);

模板类

template <typename T>
class Triplet {
  private:
    T a, b, c;

  public:
    Triplet(T a, T b, T c) : a(a), b(b), c(c) {}

    T getA() { return a; }
    T getB() { return b; }
    T getC() { return c; }
};


Triplet<int> intTriplet(1, 2, 3);
Triplet<float> floatTriplet(3.141, 2.901, 10.5);
Triplet<Person> personTriplet(Person(“Matt”), Person(“Ray”), Person(“Bob”));

模板并不仅局限于定义单个同类型变量,可以定义若干不同类型的变量,示例如下:

template <typename TA, typename TB, typename TC>
class Triplet {
  private:
    TA a;
    TB b;
    TC c;

  public:
    Triplet(TA a, TB b, TC c) : a(a), b(b), c(c) {}

    TA getA() { return a; }
    TB getB() { return b; }
    TC getC() { return c; }
};


Triplet<int, float, Person> mixedTriplet(1, 3.141, Person(“Matt”));

标准模板库

vector

#include <vector>

std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);

int first = v[1];

int outOfBounds = v.at(100);此种方式相比上面那句会检查索引值是否超出数组界限,从而抛出异常

list双向链表

#include <list>

std::list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);

链表不能使用索引值访问元素,只能通过迭代方式:

std::list<int>::iterator i;
for (i = l.begin(); i != l.end(); i++) {
    int thisInt = *i;
    // Do something with thisInt
}

其他常用容器类

set = NSSet,map = NSDictionary,pair(只存储2个值)

Shared Pointers

c++11新特性。类似于ARC,引用计数。shared pointers是栈对象,所以其会在超出作用域范围或调用reset后引用计数减1

std::shared_ptr<int> p1(new int(1)); ///< Use count = 1

if (doSomething) {
    std::shared_ptr<int> p2 = p1; ///< Use count = 2;
    // Do something with p2
}

// p2 has gone out of scope and destroyed, so use count = 1

p1.reset();

// p1 reset, so use count = 0
// The underlying int* is deleted

再来看个使用示例:

std::shared_ptr<Person> p1(new Person(“Matt Galloway”));

Person *underlyingPointer = *p1; ///< Grab the underlying pointer

p1->doADance(); ///< Make Matt dance

Objective-C++

以下示例注意c++对象的属性声明是assign,用strong或weak都无效

// Forward declare so that everything works below
@class ObjcClass;
class CppClass;

// C++ class with an Objective-C member variable
class CppClass {
  public:
    ObjcClass *objcClass;
};

// Objective-C class with a C++ object as a property
@interface ObjcClass : NSObject
@property (nonatomic, assign) std::shared_ptr<CppClass> cppClass;
@end

@implementation ObjcClass
@end

// Using the two classes above
std::shared_ptr<CppClass> cppClass(new CppClass());
ObjcClass *objcClass = [[ObjcClass alloc] init];

cppClass->objcClass = objcClass;
objcClass.cppClass = cppClass;