• C++的一些细节


    标签: C++


    1. 类的初始化

      几种不同初始化的区别:

      A a;A *a=new A()的区别,示例程序如下:

    #include <stdio.h>
    #include <string>
    #include <string.h>
    #include <iostream>
    using namespace std;
    class A{
    public:
        A(string name){
            cout<<"a instance of A : "<<name<<endl;
            this->name=name;
        }
        ~A(){
            cout<<"destory instance of A : "<<this->name <<endl;
        }
        void print(){
            cout<<this->name<<" is printing..."<<endl;
        }
    private:
        string name;
    };
    int main(){
        A a1("gqx");
        A* a2 = new A("test");
        a1.print(); 
        a2->print();
        return 0;
    }

      执行结果如下,通过A a1("gqx")形式初始化的对象,在程序结束的时候会自动回收内存,调用析构函数,而通过new方式初始化的对象需要手动释放内存。

    a instance of A : gqx
    a instance of A : test
    gqx is printing...
    test is printing...
    destory instance of A : gqx
    按 <RETURN> 来关闭窗口...

      修改主程序如下后:

    int main(){
        A a1("gqx");
        A* a2 = new A("test");
        a1.print();
        a2->print();
        delete a2;
        return 0;
    }

      执行结果如下:

    a instance of A : gqx
    a instance of A : test
    gqx is printing...
    test is printing...
    destory instance of A : test
    destory instance of A : gqx
    按 <RETURN> 来关闭窗口...

      由此可知:

    A a1("gqx"); 实例化对象在栈内存,出了作用域自动释放空间。(当然如果是全局变量,存在全局区,程序结束后由系统自动释放。)

    A* a2 = new A("test");实例化对象在堆内存,需要手动释放内存空间

      而A* a=new AA* a=new A()的区别则是:

    A* a=new A 分配一块内存空间,并将其地址传给指针a

    A* a=new A() 分配一块内存空间,并将其地址传给指针a。且后面的()表示的意思是用()中的内容对指针*a中的内容进行初始化,此处默认是空字符串。

    2. memset函数

      memset函数是内存赋值函数,用来给某一块内存空间进行赋值的,将每个字节初始化为同一值,即达到对对象的初始化,一般是对结构体的初始化,比如:

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));

    其原型是:

    void* memset(void *_Dst, int  _Val, size_t _Size)
    //_Dst是目标起始地址,_Val是要赋的值,_Size是要赋值的字节数。

    注意:memset()是逐字节拷贝的。例如int num[8];。我们用memset给num初始化为{1,1,1,1,1,1,1,1},一个int是4个字节的,8个int是32个字节,所以首先要赋值的长度就不应该为8而是32。 因为memset是逐字节拷贝,以num为首地址的8字节空间都被赋值为1, 即一个int变为0X00000001 00000001 00000001 00000001,显然,把这个数化为十进制不会等于1的。

    所以,在memset使用时要千万小心,在给char以外的数组赋值时,只能初始化为0或者-1。-1和0的补码各个位都是1和0。

    3.字符串拷贝函数

      strcpy的函数原型:

    char *strcpy(char* dest, const char *src);

    作用:把从src地址开始且含有''结束符的字符串复制到以dest开始的地址空间。

    这里需要注意的是:dest应该是一片内存的首地址,不能是没有分配内存的指针,且该对象有足够的存储空间用于存储源字符串。

    strncpy相对于strcpy函数多了一个表示可拷贝的最大字符数的参数。这样在很大程度上就能避免strcpy函数的不足(程序员在用strncpy时,需要填写拷贝个数,这时程序员就很肯能会检查一下dest是否有足够的内存)。

    char *strncpy(char *dest, const char *src, int n);

    要注意:n表示可拷贝的最大字符数,如果提前遇到'',拷贝的长度会小于n。另外,如果仅拷贝源字符串的一部分,可能会造成目标串没有字符串结束标志'';

    string类型转化为char*类型 ——C++中,c_str()的用法,就是把 string 转成 char*

    string str="yoooo";
    char *a=str.c_str();

    4.malloc使用的时候为什么要加上强制类型转换

      举例如下,为一个结构体数组申请内存空间的时候,常常会使用如下语句:

    ep_events = (struct epoll_event*)malloc(sizeof(struct epoll_event)*EPOLL_SIZE);

    经常会在前面添加一个强制类型转换语句,如果不使用,如下:

    ep_events = malloc(sizeof(struct epoll_event)*EPOLL_SIZE);

    编译器会报错:

    epolltest.cpp:46:23: error: invalid conversion fromvoid*’ to ‘epoll_event*’ [-fpermissive]
         ep_events = malloc(sizeof(struct epoll_event)*EPOLL_SIZE);

    大概的意思是,malloc返回的是一个void*类型指针,编译器在编译的时候无法将其自动转换成struct epoll_event*类型的指针,需要我们手动强制转换。

    5. printf

      printf是一个行缓冲函数,先写到缓冲区,满足条件后,才将缓冲区刷到对应文件中,刷缓冲区的条件如下:

    1. 缓冲区填满

    2. 写入的字符中有‘ ’ ' '

    3. 调用fflush手动刷新缓冲区

    4. 调用scanf要从缓冲区中读取数据时,也会将缓冲区内的数据刷新。

    做如下实验:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include<unistd.h>
    using namespace std;
    ​
    int main(int argc, char *argv[])
    {
        printf("test");
        sleep(10);
        return 0;
    }

    10秒之后才打印test,中途Ctrl+C则不会打印test。如果打印语句换成以下形式:

     printf("test
    ");

    程序运行时刻打印test。

     6. 补充中。。。

  • 相关阅读:
    silverlight第三方控件
    Net4.0 Parallel编程(二)Data Parallelism 中_转
    html鼠标的各种形状
    C# Using用法三则
    让ExtJS里的GridPanel的列能够自动决定宽度
    extjs menu几个有用的属性
    ie中jQuery无法解析xml文件的解决方案
    .Net4.0 Parallel编程(一)Data Parallelism 上_转
    祝贺Silverlight 4 Tools 中文版发布
    .Net 4.0 ExpandoObject 使用(上)_转
  • 原文地址:https://www.cnblogs.com/helloworldcode/p/11115990.html
Copyright © 2020-2023  润新知