20170810

#include "stdio.h"
#include <iostream>
using namespace std;
/*********************************************************/
/*               指针学习                                */
/*********************************************************/
int fun(char *s)
{
    int num = 0;
    num += *s;
    s++;

    return num;
}

/*
因为"hello world!"是一个字符串常量,存放在静态数据区,
把该字符串常量存放的静态数据区的首地址赋值给了指针,
returnStr函数退出时,该该字符串常量所在内存不会被回收,
回为操作的一直是这个静态数据区,故能够通过指针顺利无误的访问。
*/
//char *returnStr()
//{
//    char *p = "hello world!";
//    return p;
//}

/*
"hello world!"是一个字符串常量,存放在静态数据区,没错,
但是把一个字符串常量赋值给了一个局部变量(char []型数组),
该局部变量存放在栈中,相当于把静态数据赋值给局部变量后,
操作的是这个局部变量。这是与前着最本质的区别,当returnStr函数退出时,栈要清空,
局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,所以打印出来的是乱码。
*/
//char *returnStr()
//{
//    char p[] = "hello world!";
//    return p;
//}

//如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型
//char *returnStr()
//{
//    static char p[] = "hello world!";
//    return p;
//}
//
//int main()
//{
//    char *str;
//    str = returnStr();
//    printf("%s\n", str);
//
//    int b;
//    char str1[] = "abcdefghijklmn";
//    b = fun(str1);                  //在函数体内对s进行自加1,但是不意味着同时对str进行加1运算
//
//    char a[20] = "you are a girl";
//    cout << "整个数组的首地址:" << &a << endl;
//    cout << "首元素的首地址:"   << &a[0] << endl;
//    cout << "首元素的首地址:"   << a << endl;
//    cout << "下一个元素的首地址:"<< &a[1] << endl;
//
//    int *p1[10];                  //[]等级高 所以是指针数组,数组中存放的都是int*的指针
//    int b1[10];
//    int(*p2)[10] = & b1;           //()优先级高于[],所以是数组指针,也就是指针指向的是一个int型的数组
//
//    int *ptr = (int*)a;
//    cout << ptr << endl;        //ptr = &a = 002DFC48
//    ptr += 5;                   //指针加上5 编译器是将PTR的值加上5*sizeof(int) = 5*4 =20
//    cout << ptr << endl;
//    
//    
//    system("pause");
//    return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*********************************************************/
/*               函数返回值的问题                        */
/*********************************************************/
//#include <stdio.h>  
//
返回的是局部变量的地址,该地址位于动态数据区,栈里  
//char *s1()
//{
//    char p[] = "Hello world!";
//    printf("in s1 p=%p\n", p);
//    printf("in s1: string's address: %p\n", &("Hello world!"));
//    return p;
//}
//
返回的是字符串常量的地址,该地址位于静态数据区  
//char *s2()
//{
//    char *q = "Hello world!";
//    printf("in s2 q=%p\n", q);
//    printf("in s2: string's address: %p\n", &("Hello world!"));
//    return q;
//}
//
返回的是静态局部变量的地址,该地址位于静态数据区  
//char *s3()
//{
//    static char r[] = "Hello world!";
//    printf("in s3 r=%p\n", r);
//    printf("in s3: string's address: %p\n", &("Hello world!"));
//    return r;
//}
//
//int main()
//{
//    char *t1, *t2, *t3;
//    t1 = s1();
//    t2 = s2();
//    t3 = s3();
//    printf("in main:");
//    printf("p=%p, q=%p, r=%p\n", t1, t2, t3);
//    printf("%s\n", t1);
//    printf("%s\n", t2);
//    printf("%s\n", t3);
//    system("pause");
//    return 0;
//}

//函数返回时,先将返回值存入寄存器,
//然后释放局部变量空间,最后return. fn()返回j其实是返回j的一个拷贝出来。
//int fn()
//{
//    int j= 3;
//    return j;
//}
//char* test()
//{
//    char a[] = "hello "; //乱码
//    //char *a = "hello ";  //ok
//    //static char a[] = "hello"; //ok
//    return a;
//}
//int main(int argc, char* argv[])
//{
//    printf("%d\n", fn());
//    printf("%s\n", test());
//    system("pause");
//    return 0;
//}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*********************************************************/
/*               重载覆盖和隐藏                         */
/*********************************************************/
//( 1)函数 Derived::f(float)覆盖了 Base::f(float)。
//
//( 2)函数 Derived::g(int)隐藏了 Base::g(float),而不是重载。!!!!!!!!!!!!!!!!!!!!!!!!
//
//( 3)函数 Derived::h(float)隐藏了 Base::h(float),而不是覆盖。
//class Base
//{
//public:
//    virtual  void f(float x)
//    {
//        cout << "Base::f(float) " << x << endl;
//    }
//    void g(float x)
//    {
//        cout << "Base::g(float) " << x << endl;
//    }
//    void h(float x){ cout << "Base::h(float) " << x << endl; }
//};
//class Derived : public Base
//{
//public:
//    virtual  void f(float x)
//    {
//        cout << "Derived::f(float) " << x << endl;
//    }
//    void g(char x)
//    {
//        cout << "Derived::g(int) " << x << endl;
//    }
//    void h(float x){ cout << "Derived::h(float) " << x << endl; }
//};
//
//void main(void)
//{
//    Derived  d;
//    Base *pb = &d;
//    Derived *pd = &d;
//    // Good : behavior depends solely on type of the object  
//    pb->f(3.14f);  // Derived::f(float) 3.14   
//    pd->f(3.14f); // Derived::f(float) 3.14  
//    // Bad : behavior depends on type of the pointer  
//    pb->g(3.14f);  // Base::g(float) 3.14   
//    pd->g(3.14f);  // Derived::g(char) 3        (surprise!) 隐藏掉了 只能调用继承类函数
//    // Bad : behavior depends on type of the pointer  
//    pb->h(3.14f);  // Base::h(float) 3.14      (surprise!)  
//    pd->h(3.14f);  // Derived::h(float) 3.14   
//}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*********************************************************/
/*               友元                                    */
/*********************************************************/
//class  MyClass
//{
//public:
//    MyClass(string name)
//    {
//        m_name = name;
//    }
//
//    //声明一个友元函数  
//    friend  void  Display(MyClass &mycalss);
//    friend  ostream& operator<< (ostream &os, MyClass &ob);
//protected:
//    string  m_name;
//};
//
定义这个友元函数  
不要写成 void MyClass::Display(MyClass &mycalss)    
//void  Display(MyClass &mycalss)
//{
//    cout << "Access Protected data : "<< mycalss.m_name << endl;
//}
//
测试  
//int main(int argc, char* argv[])
//{
//    MyClass test("Class A");
//
//    Display(test);
//
//    return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
//#include <iostream>  
//using namespace std;
//
//class Base{
//public:
//    virtual ~Base() { cout << "~B" << endl; }
//};
//
//class Derived :public Base{
//public:
//    ~Derived() { cout << "~D" << endl; }
//};
//
//int main()
//{
//    Base *b = new Derived; //注意这里  
//    delete b;  //先调用派生类析构 再调用子类析构
//}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*********************************************************/
/*              拷贝构造函数                             */
/*********************************************************/

/*
对象以值传递的方式传入函数参数
调用g_Fun()时,会产生以下几个重要步骤:
(1).test对象传入形参时,会先会产生一个临时变量,就叫 C 吧。
(2).然后调用拷贝构造函数把test的值给C。 整个这两个步骤有点像:CExample C(test);
(3).等g_Fun()执行完后, 析构掉 C 对象。
*/
//class CExample
//{
//private:
//    int a;
//
//public:
//    //构造函数  
//    CExample(int b)
//    {
//        a = b;
//        cout << "creat: " << a << endl;
//    }
//
//    //拷贝构造  
//    CExample(const CExample& C)
//    {
//        a = C.a;
//        cout << "copy" << endl;
//    }
//
//    //析构函数  
//    ~CExample()
//    {
//        cout << "delete: " << a << endl;
//    }
//
//    void Show()
//    {
//        cout << a << endl;
//    }
//};
//
全局函数,传入的是对象  
//void g_Fun(CExample C)
//{
//    cout << "test" << endl;
//}
//
//int main()
//{
//    CExample test(1);
//    //传入对象  
//    g_Fun(test);
//
//    return 0;
//}

//对象以值传递的方式从函数返回,也是调用拷贝构造函数
//class CExample
//{
//private:
//    int a;
//
//public:
//    //构造函数  
//    CExample(int b)
//    {
//        a = b;
//    }
//
//    //拷贝构造  
//    CExample(const CExample& C)
//    {
//        a = C.a;
//        cout << "copy" << endl;
//    }
//
//    void Show()
//    {
//        cout << a << endl;
//    }
//};
//
全局函数  
//CExample g_Fun()
//{
//    CExample temp(0);
//    return temp;
//}
//
//int main()
//{
//    g_Fun();
//    return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*
默认的拷贝构造函数不能对static变量进行处理,需要手动添加
*/
//class Rect
//{
//public:
//    Rect()      // 构造函数,计数器加1  
//    {
//        count++;
//        cout << "constrctor" << endl;
//    }
//    ~Rect()     // 析构函数,计数器减1  
//    {
//        count--;
//        cout << "destrctor" << endl;
//    }
//    static int getCount()       // 返回计数器的值  
//    {
//        return count;
//    }
//private:
//    int width;
//    int height;
//    static int count;       // 一静态成员做为计数器  
//};

//class Rect
//{
//public:
//    Rect()      // 构造函数,计数器加1  
//    {
//        count++;
//    }
//    Rect(const Rect& r)   // 拷贝构造函数  
//    {
//        width = r.width;
//        height = r.height;
//        count++;          // 计数器加1  
//    }
//    ~Rect()     // 析构函数,计数器减1  
//    {
//        count--;
//    }
//    static int getCount()   // 返回计数器的值  
//    {
//        return count;
//    }
//private:
//    int width;
//    int height;
//    static int count;       // 一静态成员做为计数器  
//};
//int Rect::count = 0;        // 初始化计数器  
//
//int main()
//{
//    Rect rect1;
//    cout << "The count of Rect: " << Rect::getCount() << endl;
//
//    Rect rect2(rect1);   // 使用rect1复制rect2,此时应该有两个对象  
//    cout << "The count of Rect: " << Rect::getCount() << endl;
//
//    return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*
默认拷贝构造函数不能对动态分配空间,需要手动重写拷贝构造函数
*/
class Rect
{
public:
    Rect()      // 构造函数,p指向堆中分配的一空间  
    {
        p = new int(100);
    }
    ~Rect()     // 析构函数,释放动态分配的空间  
    {
        if (p != NULL)
        {
            delete p;
        }
        cout << "deconstrctor" << endl;  //析构一次 但是同一个内存
    }
private:
    int width;
    int height;
    int *p;     // 一指针成员  
};
//class Rect
//{
//public:
//    Rect()      // 构造函数,p指向堆中分配的一空间  
//    {
//        p = new int(100);
//    }
//    Rect(const Rect& r)
//    {
//        width = r.width;
//        height = r.height;
//        p = new int;    // 为新对象重新动态分配空间  
//        *p = *(r.p);
//    }
//    ~Rect()     // 析构函数,释放动态分配的空间  
//    {
//        if (p != NULL)
//        {
//            delete p;
//        }
//        cout << "deconstrctor" << endl;  //重新分配空间 析构两次
//    }
//private:
//    int width;
//    int height;
//    int *p;     // 一指针成员  
//};
//int main()
//{
//    Rect rect1;
//    Rect rect2(rect1);   // 复制对象  
//    return 0;
//} 

/*
验证const如何区分重载
1.按值传递时,对用户而言,这是透明的,用户不知道函数对形参做了什么,
在这种情况下重载是没有意义的,所以规定不能重载。
2.当指针或引用被引入时,用户就会对函数的操作有了一定的了解,
不在是透明的,这时重载是有意义的,所以规定可以重载。
*/
//class A
//{
//public:
//    void f(int i){ cout << "无const" << endl; }
//    void f(int i)const{ cout << "有const" << endl; }
//    //void f(const int i){ cout << "const在参数中" << endl; }  //没有意义,不允许重载
//    void f(int&){ cout << "int&" << endl; }
//    void f(const int&){ cout << "const int&" << endl; }
//};
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
//void test_static()
//{
//    static int Temp = 1;
//    Temp++;
//    printf("Temp is :%d\n", Temp);
//}
//
//int main(int argc, char *argv[])
//{
//    A a;
//    cout << a.c1 << endl;
//    
//    int i = 0;
//    for (i = 0; i <= 4; i++)
//    {
//        test_static();
//    }
//
//    system("pause");
//}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值