namespace std{
template
void swap(T& a, T& b){
T temp(a); // T要满足拷贝构造和拷贝赋值
a = b;
b = temp;
}
}
case 1:
temp j;
for(int i = 0; i < n; ++ i){
j = func(i);
}
case 2:
for(int i = 0; i < n; ++ i){
temp j(i);
}
方案1调用了1次构造、1次析构和n次赋值
方案2调用了n次构造和n次析构
如果对程序效率不敏感,则方案2更好
(T) expression;
T(expression);
int x, y;
double d = static_cast (x) / y;
// 自定义变量
class Widget{
public:
explicit Widget(int size);
};
void dosomework(const Widget& w);
dosomework(Widget(15)); // function-style cast
dosomework(static_cast(15)); // c++ style cast
#include
using namespace std;
class Base{
public:
int a;
};
class Derived:public Base{
public:
double c;
virtual void bar(){}
};
void test(Base* base, Derived* derived){
printf("%p, %p", base, derived); // 0x16fab2c58, 0x16fab2c50
printf("%p\n", static_cast (derived)); // 0x16fab2c58
if(base == static_cast (derived)){
cout << "==" << endl; // ==
}else{
cout << "!=" << endl;
}
}
int main(){
Derived derived;
test(&derived, &derived);
return 0;
}
类中含有虚指针,8个字节,staticcast会移动类的指针
在运行时类型转换,开销很大
以引用的方式返回的成员需要注意,因为可能会提高他的访问级别,导致被外部修改
class Point{
public:
Point(int x, int y);
void setX(int newVal);
void setY(int newVal);
};
struct RectData{
Point ulhc; // upper left-hand corner
Point lrhc; // lower right-hand corner
};
class Rectangle{
public:
Point& upperLeft() const { return pData->ulhc;} // const承诺不修改其中的成员变量
Point& lowerRight() const{ return pData->lrhc;}
private:
std::shared_ptr pData;
};
int main(){
Point coord1(0, 0);
Point coord2(100, 100);
const Rectangle rec(coord1, coord2); // const表示成员状态不会变
rec.upperLeft().setX(50); // 由于upperLeft返回的是引用,再调用setx就把成员状态更改了
}
为了防止上边那种意料之外的修改,我们可以这样更改:
class Rectangle{
public:
const Point& upperLeft() const { return pData->ulhc;} // 增加const,返回一个const的指针
const Point& lowerRight() const{ return pData->lrhc;}
private:
std::shared_ptr pData;
};
class GUIObject {...};
const Rectangle boundingBox(const GUIObject& obj);
GUIObject *pgo; // make pgo point to some GUIObject
const Point *pUperLeft = &(boundingBox(*pgo).upperLeft());
// 返回一个临时变量的地址,在临时变量被释放后,操作pUperLeft会导致未定义行为
// 应当用一个变量接收
auto bbox = boundingBox(*pgo);
const Point* pUpperLeft = &(bbox.uperLeft());
class Menu{
Mutex mutex;
Image *bgImage;
int imageChanges;
public:
void changeBackground(std::istream& imgSrc);
};
void Menu::changeBackground(std::istream& imgSrc){
lock(&mutex);
delete bgImage;
++ imageChanges;
bgImage = new Image(imgSrc); // 如果这一步没有new成功,会导致资源泄漏(锁未释放)、数据损坏(背景被删除、改变次数+1)
unlock(&mutex);
}
异常安全(exception-safe functions):
上面的代码应该这样修改:
class Menu{
Mutex mutex;
std::shared_ptr bgImage;
int imageChanges;
public:
void changeBackground(std::istream& imgSrc);
};
void Menu::changeBackground(std::istream& imgSrc){
Lock ml(&mutex); // item14:acquire mutex and ensure its later release(RAII)
bgImage.reset(new Image(imgSrc));
++ imageChanges;
}