C++ 指針和const的討論

 

該博客主要關於指針的相關信息,包含普通指針和共享指針以及const的討論ios

#include <iostream>
#include <memory>

using namespace std;

// 對於普通類型指針
#define PTR(X)       X*                // 普通指針
#define CONST_PTR(X) const X*          // 指針內容不可修改
#define PTR_CONST(X) X* const          //  指針不可修改
#define CONST_PTR_CONST(X) const X* const // 指針和指針內容不可修改

// Ptr: 普通共享指針
// ConstPtr: 不可修改內容的共享指針
// PtrConst: 不可修改指針的共享指針,內容能夠修改
// ConstPtrConst: 只能初始化的指針,不能作任何的修改動做
#define SHARED_PTR_DEFINE(X) \
    public: \
    typedef std::shared_ptr<X> Ptr;  \
    typedef std::shared_ptr<const X> ConstPtr;  \
    typedef const std::shared_ptr<X> PtrConst; \
    typedef const std::shared_ptr<const X> ConstPtrConst;

class testA
{
    SHARED_PTR_DEFINE(testA)
    public:
        testA()
    {
        a = 10000;
    }

public:
    void print() const
    {
        std::cout << "a = " << a << std::endl;
    }

public:
    int a;
};

#if 0
void print(PTR(testA) p)
{
    p->print();

    p->a = 10;

    p = new testA;

    p->print();
}

void print(CONST_PTR(testA) p)
{
    p->print();

    //    p->a = 10;  // error
}

// error print(PTR(testA) p) 重定義
//void print(PTR_CONST(testA) p)
//{
//    p->print();

//    p->a = 10;

//    p = new testA(); // error
//}

// error print(CONST_PTR(testA) p) 重定義
// void print(CONST_PTR_CONST(testA) p)
// {
//    p->print();
// }

#endif

#if 1
void print(testA::Ptr p)
{
    std::cout << "B: p = " << p.use_count()
              << ", p address = " << (unsigned long long int)(&p)
              << ", p pointer address = " << (unsigned long long int)(p.get()) << std::endl;

    std::cout << "run here 3" << std::endl;
    p->print();

    p->a = 100;

     p->print();

    p.reset(new testA);

    p->print();

    std::cout << "C: p = " << p.use_count()
              << ", p address = " << (unsigned long long int)(&p)
              << ", p pointer address = " << (unsigned long long int)(p.get()) << std::endl;
}

// 共享指針對象是傳值,可是,對於指針的修改一樣有效
void print(testA::ConstPtr p)
{
    std::cout << "run here 2" << std::endl;
    p->print();

    // p->a = 1; // error

    p.reset(new testA);

    p->print();
}

// error: print(test::Ptr p) 重定義
//void print(testA::PtrConst p)
//{
//    p->print();

//    p->a = 1;

    p.reset(new testA);// error

//    p->print();
//}

//error: print(testA::ConstPtr p) 重定義
//void print(testA::ConstPtrConst p)
//{
//    p->print();

    p->a = 1; // error

    p.reset(new testA); // error
//}

#else
// 共享指針傳地址
void print(testA::Ptr& p)
{
    std::cout << "B: p = " << p.use_count()
              << ", p address = " << (unsigned long long int)(&p)
              << ", p pointer address = " << (unsigned long long int)(p.get()) << std::endl;

    std::cout << "run here 3" << std::endl;
    p->print();

    p->a = 1;

    p.reset(new testA);

    p->print();

    std::cout << "C: p = " << p.use_count()
              << ", p address = " << (unsigned long long int)(&p)
              << ", p pointer address = " << (unsigned long long int)(p.get()) << std::endl;
}

void print(testA::ConstPtr& p)
{
    std::cout << "run here 4" << std::endl;
    p->print();

    // p->a = 1; // error

    p.reset(new testA);

    p->print();
}

void print(testA::PtrConst& p)
{
    std::cout << "run here 5" << std::endl;
    p->print();

    p->a = 1;

    //    p.reset(new testA);// error

    p->print();
}

void print(testA::ConstPtrConst& p)
{
    std::cout << "run here 6" << std::endl;
    p->print();

    //    p->a = 1; // error

    //    p.reset(new testA); // error
}
#endif

int main()
{
#if 0
    PTR(testA) p00 = new testA();

    PTR(testA) p0 = new testA();

    p0->print();

    p0 = new testA();

    p0 = p00;

    // 指針內容不可修改

    CONST_PTR(testA) p = new testA(); // p的內容是const
    p->print();

    //    p->a = 2;  // error, 不容許修改指針所指內容

    // 指針不可修改
    PTR_CONST(testA) p1 = new testA(); // p1是const

    p1->a  = 1;

    p1->print();

    //    p = p1; // error, 不容許修改指針

    // 指針和指針內容不可修改
    CONST_PTR_CONST(testA) p2 = new testA();

    p2->print();

    //    p2->a = 1; // error

    //    p2 = p1; // error



#else
    testA::Ptr p(new testA());

    p->a = 2;

    p->print();

    testA::Ptr p1(new testA());

    p = p1;

    p->print();

    // 內容不能夠修改的指針
    testA::ConstPtr p2(new testA());

    p2->print();

    //    p2->a = 3; // error,指針所指的內容不能夠修改

    p2.reset(new testA());  // 容許修改指針

    p2->print();

    // 指針不能夠修改的指針
    testA::PtrConst p3(new testA());

    p3->a = 4;  //

    //    p3.reset(new testA()); // error 不容許修改指針

    // 只能初始化的指針
    testA::ConstPtrConst p4(new testA());

    p4->print();

    //    p4.reset(new testA()); // error 不容許修改指針

    //    p4->a = 5;    // error 不容許修改指針所指的內容

    // 共享指針對象傳地址也可以將修改的指針信息返回: 用於驗證引用
    std::cout << "A p = " << p.use_count()
              << ", p address = " << (unsigned long long int)(&p)
              << ", p pointer address = " << (unsigned long long int)(p.get()) << std::endl;
    print(p);

    std::cout << "D p = " << p.use_count()
              << ", p address = " << (unsigned long long int)(&p)
              << ", p pointer address = " << (unsigned long long int)(p.get()) << std::endl;
#endif
    return 0;
}
相關文章
相關標籤/搜索