重学c++(五)

一、void*、NULL、nullptr

1、c++11中,nullptr代替(void*)0,NULL只表示0

2、代码(vs2015中结果)

#include"stdafx.h"

void func(void* i)
{
    cout << "func(void* i)" << endl;
}
void func(int i)
{
    cout << "func(int i)" << endl;
}

int main()
{ 
    int* pi = NULL;
    int* pi2 = nullptr;
    char* pc = NULL;
    char* pc2 = nullptr;
    func(NULL);            //func(int i)
    func(nullptr);        //func(void* i)
    func(pi);            //func(void* i)
    func(pi2);            //func(void* i)
    func(pc);            //func(void* i)
    func(pc2);            //func(void* i)

    return 0;
 }

二、C++类型转换

1、const_cast:用于转换指针或引用,去掉类型的const属性

    const int a = 10;
    int* pA = const_cast<int*>(&a);

2、reinterpret_cast:重新解释类型,既不检查指向的内容也不检查指针类型本身;但要求转换前后类型所占用内存大小一致,否则将引发编译时错误=====》》》》用户可以做任何操作,但要为自己的行为负责

typedef void(*FuncPtr)();
FuncPtr funcPtr;
funcPtr = reinterpret_cast<FuncPtr>(&Test);
/*int Test(void)
{
    return 0;
}/*

 3、static_cast:用于基本类型转换,有继承关系类对象和类指针之间转换,由程序员来确保是安全的,它不会产生动态转换的类型安全检查的开销

int i = 5;
double d = static_cast<double>(i);

4、dynamic_cast:只能用于含有虚函数的类,必须用在多态体系中,用于类层次间的向上和向下转化;向下转化时,如果是非法的对于指针返回NULL 

#include"stdafx.h"

class Base
{
public:
    Base() :_i(0){};
    virtual void T() { cout << "Base:T" << _i << endl; }
private:
    int _i;
};
class Derived :public Base
{
public:
    Derived() :_j(1) {};
    virtual void T() { cout << "Derived:T" << _j << endl;; }
private:
    int _j;
};

int main()
{ 
    Base cb;
    Derived cd; 
    Base* pcb;
    Derived* pcd;
    //向上
    pcb = dynamic_cast<Base*>(&cd);
    if (pcb == nullptr)
        cout << "unsafe dynamic_cast from Derived to Base" << endl;

    //向下
    pcd = dynamic_cast<Derived*>(&cb);
    if (pcd == nullptr)
        cout << "unsafe dynamic_cast from Base to Derived" << endl;
    return 0;
}

三、适配器(Adapter)模式(接四)

1、适配器将类接口转换为客户端期望的另一个接口;使用适配器可防止类由于接口不兼容而不一起工作;适配器模式的动机是如果可以更改接口则可以重用现有软件

 2、代码

class LegacyRectangle
{
public:
    LegacyRectangle(double x1, double y1, double x2, double y2)
    {
        _x1 = x1;
        _y1 = y1;
        _x2 = x2;
        _y2 = y2;
    }
    void LegacyDraw(string str)
    {
        cout << "LegacyRectangle::LegacyDraw:" << str<< " "<< _x1 << " " << _y1 << " " << _x2 << " " << _y2 << endl;
    }
private:
    double _x1;
    double _y1;
    double _x2;
    double _y2;
};

class Rectangle
{
public:
    virtual void Draw(string str) = 0;
};

 //第一种适配的方式:多重继承(会出现钻石继承情况:接口继承可避免)
class RectangleAdapter :public Rectangle, public LegacyRectangle
{
public:
    RectangleAdapter(double x, double y, double w, double h) :
        LegacyRectangle(x, y, x + w, y + h)
    {
        cout << "RectangleAdapter(double x, double y, double w, double h)" << endl;
    }
    virtual void Draw(string str)
    {
        cout << "RectangleAdapter::Draw" << endl;
        LegacyDraw(str);
    }
};

//组合方式的Adapter
class RectangleAdapter2 :public Rectangle
{
public:
    RectangleAdapter2(double x, double y, double w, double h) :
        _IRect(x, y, x + w, y + h)
    {
        cout << "RectangleAdapter2(double x, double y, double w, double h)" << endl;
    }
    virtual void Draw(string str)
    {
        cout << "RectangleAdapter2::Draw" << endl;
        _IRect.LegacyDraw(str);
    }
private:
    LegacyRectangle _IRect;
};

int main()
{ 
    double x = 20.0, y = 50.0, w = 300.0, h = 100.0;
    RectangleAdapter ra(x, y, w, h);
    Rectangle* pR = &ra;
    pR->Draw("Testing");

    cout << "--------------" << endl;
    RectangleAdapter2 ra2(x, y, w, h);
    Rectangle* pR2 = &ra2;
    pR2->Draw("Testing2");

    return 0;
}

 

posted @ 2021-09-29 11:21  学学学学学ll  阅读(49)  评论(0)    收藏  举报