#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) { // 拷貝構(gòu)造函數(shù)
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) { // 傳遞對象的時候會調(diào)用拷貝構(gòu)造函數(shù)
b.setName("000");
}
void fun2(B& b) { // 傳遞對象引用的時候不會調(diào)用拷貝構(gòu)造函數(shù),這種方式更好
b.setName("111");
}
// new 創(chuàng)建對象會一直存在,容易造成內(nèi)存泄露,直到 delete 掉該對象
// 局部變量和傳遞的參數(shù)會存到 棧 中
int main()
{
printf("main begin\n");
foo();
A* a;
{
B b("localB"); // 作用域是大括號決定的
printf("fun begin\n");
fun(b);
printf("fun end\n"); // 這個在調(diào)用fun結(jié)束后,調(diào)用了一次析構(gòu)函數(shù),來自拷貝構(gòu)造函數(shù)
B b2("localB2");
b2.print();
printf("fun2 begin\n");
fun2(b2);
b2.print();
printf("fun2 end\n");
a = new A("newLocalA"); // 不會在大括號結(jié)束的時候自動調(diào)用析構(gòu)函數(shù),始終不會銷毀,直到調(diào)用 delete。
}
delete a;
printf("main end\n");
return 0;
}
輸出結(jié)果:
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)