c++ 对象的作用域与内存分配

2016-09-21  本文已影响17人  czins
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class A {
    public:
    A(const char* name): m_name(name) {
        printf("A(%s)\n", m_name);
    }
    ~A() {
        printf("~A(%s)\n", m_name);
    }
    private:
    const char* m_name;
};

class B {
    public:
    B(const char* name): m_name(name) {
        printf("B(%s)\n", m_name);
    }
    B(const B& b) : m_name(b.m_name) { // 拷贝构造函数
        printf("拷贝 B(%s)\n", m_name);
    }

    ~B() {
        printf("~B(%s)\n", m_name);
    }
    void print() {
        printf("m_name:%s\n", m_name);
    }
    void setName(const char* name) {
        m_name = name;
    }

    private:
    const char* m_name;
};

A a("globalA");

B b("globalB");

void foo() {
    printf("foo begin\n");
    A a("localA");
    static B b("staticB");
    printf("foo end\n");
}

void fun(B b) { // 传递对象的时候会调用拷贝构造函数
    b.setName("000");
}

void fun2(B& b) { // 传递对象引用的时候不会调用拷贝构造函数,这种方式更好
    b.setName("111");
}

// new 创建对象会一直存在,容易造成内存泄露,直到 delete 掉该对象

// 局部变量和传递的参数会存到 栈 中

int main()
{
    printf("main begin\n");
    foo();
    A* a;
    {
        B b("localB"); // 作用域是大括号决定的

        printf("fun begin\n");
        fun(b);
        printf("fun end\n");  // 这个在调用fun结束后,调用了一次析构函数,来自拷贝构造函数

        B b2("localB2");
        b2.print();

        printf("fun2 begin\n");
        fun2(b2);
        b2.print();
        printf("fun2 end\n");

        a = new A("newLocalA"); // 不会在大括号结束的时候自动调用析构函数,始终不会销毁,直到调用 delete。
    }
    delete a;
    printf("main end\n");
    return 0;
}

输出结果:

A(globalA)
B(globalB)
main begin
foo begin
A(localA)
B(staticB)
foo end
~A(localA)
B(localB)
fun begin
拷贝 B(localB)
~B(000)
fun end
B(localB2)
m_name:localB2
fun2 begin
m_name:111
fun2 end
A(newLocalA)
~B(111)
~B(localB)
~A(newLocalA)
main end
~B(staticB)
~B(globalB)
~A(globalA)
上一篇下一篇

猜你喜欢

热点阅读