虚函数
先来看个错误示例:
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;