总结:

1、类对象的作用域为两个{}之间。在遇到}后开始执行析构函数

2、当没有任何显式的构造函数(无参,有参,拷贝构造)时,默认构造函数才会发挥作用

一旦提供显式的构造函数,默认构造函数不复存在,默认构造函数都会被覆盖掉。若想调用,则显示提供默认构造函数

3、析构函数不能重载,没有参数,没有返回值。显示提供析构,默认析构就会被覆盖掉

4、当调用默认构造函数时,类对象的数据成员值是在栈上随机分配的随机值

5、当没有显式的拷贝构造函数时,默认拷贝构造才会出现

6、每个类对象都会有默认的拷贝构造函数  但只是单纯的将一个类对象的数据成员变量赋值给本身

//构造函数是对象初始化的时候调用
    Test t3 = t1;  //初始化t3时调用t3构造函数 依然是调用t3的拷贝构造函数
    t3.printT();

Test t4;  //已经调用默认无参构造函数 初始化
    t4 = t1; //调用的不是t4拷贝构造函数,而是t4的赋值操作符函数

7、需要有额外空间释放时,调用析构函数。否则无需显式写出。

8、析构函数的作用,并不是删除对象,而在对象销毁前完成的一些清理工作。对象的释放是由操作系统控制(存放在栈)

9、当没有显式的析构函数时,默认析构函数被调用

10、析构函数的调用顺序 和构造相反:谁先构造,谁后析构  (栈结构)

11、当类的数据成员中有指针时,拷贝构造函数必须显式说明(为指针所存内存开辟空间)同时析构函数 手动释放空间

12、拷贝构造函数的应用场景:

<1>Test t2 = t1; //⽤对象t1 初始化 对象 t2

<2>Test t2(t1); //⽤对象t1 初始化 对象 t2

<3>void func(Test p) //会执⾏ p = t1 的操作,p会调⽤copy构造函数进⾏初始化

<4>函数的返回值是⼀个元素 (复杂类型的), 返回的是⼀个新的匿名对象(所以会调⽤匿名对象类的copy构造函数

注意:

有关 匿名对象的去和留

如果⽤匿名对象 初始化 另外⼀个同类型的对象, 匿名对象 转成有名对象

如果⽤匿名对象 赋值给 另外⼀个同类型的对象, 匿名对象 被析构

13、系统提供默认的拷贝构造器,一经定义不再提供。但系统提供的默认拷贝 构造器是 等位拷贝,也就是通常意义上的浅拷贝。如果类中包含的数据元素全部在栈上,浅拷贝 也可以满足需求的。但如果堆上的数据,则会发生多次析构行 为。

14、如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成 员它只有一个带参数的构造函数,没有默认构造函数。这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,

15、构造函数的初始化列表  初始化对象时需要用到
       构造对象成员的顺序跟初始化列表的顺序无关
       而是跟成员对象的定义顺序有关

16、在构造函数执行时,先执行初始化列表,实现变量的初始化,然后再执行函数内部的语句

17、

《C++ Primer》中提到在以下三种情况下需要使用初始化成员列表:

情况一、需要初始化的数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化);

情况二、需要初始化const修饰的类成员或初始化引用成员数据;

情况三、子类初始化父类的私有成员;

情况一的说明:数据成员是对象,并且这个对象只有含参数的构造函数,没有无参数的构造函数;

如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错。

情况二的说明:对象引用或者cosnt修饰的数据成员

情况二:当类成员中含有一个const对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化,因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。

情况三的说明:子类初始化父类的私有成员,需要在(并且也只能在)参数初始化列表中显示调用父类的构造函数,因为只有初始化列表可以构造父类的private成员(通过显示调用父类的构造函数)

18、构造函数就是用来初始化自己数据成员的。所以先有构造函数的调用,再有数据成员的初始化(若有继承关系,先调用父类构造函数,在调用子类构造函数,再初始化数据成员,再执行构造函数中的语句。)

class Test{
public:Test(){};Test (int x){ int_x = x;};void show(){cout<< int_x << endl;}
private:int int_x;
};
class Mytest:public Test{
public:Mytest() :Test(110){//Test(110);            //  构造函数只能在初始化列表中被显示调用,不能在构造函数内部被显示调用};
};
int _tmain(int argc, _TCHAR* argv[])
{Test *p = new Mytest();p->show();return 0;
}

结果:如果在构造函数内部被显示调用输出结果是:-842150451(原因是这里调用了无参构造函数);

如果在初始化列表中被显示调用输出结果是:110

参考自https://blog.csdn.net/sinat_20265495/article/details/53670644

17、使用构造函数初始化列表的好处:

类对象的构造顺序显示,进入构造函数体后,进行的是计算,是对成员变量的赋值操作,显然,赋值和初始化是不同的,这样就体现出了效率差异,如果不用成员初始化类表,那么类对自己的类成员分别进行的是一次隐式的默认构造函数的调用,和一次赋值操作符的调用,如果是类对象,这样做效率就得不到保障

注意:构造函数需要初始化的数据成员,不论是否显示的出现在构造函数的成员初始化列表中,都会在该处完成初始化,并且初始化的顺序和其在类中声明时的顺序是一致的,与列表的先后顺序无关,所以要特别注意,保证两者顺序一致才能真正保证其效率和准确性。

01构造和析构函数

# if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Test {
public://test类的构造函数//在对象被创建的时候,用来初始化对象的函数Test()//无参数的构造函数{m_x = 0;m_y = 0;}Test(int x){m_x = x;m_y = 0;}Test(int x, int y) {m_x = x;m_y = y;name = (char *)malloc(100);strcpy(name, "zhangsan");}void printT(){cout << "x = " << m_x << "  y = " << m_y << endl;}//析构函数和构造函数都没有返回值,//析构函数没有形参~Test() {cout << "~Test 执行" << endl;if (name != NULL){free(name);name = NULL;cout << "free succ!" << endl;}}
private:int m_x;int m_y;char *name;
};void test01() {Test t1(10, 20);  //类对象的作用域为两个{}之间。在遇到}后开始执行析构函数t1.printT();Test t2(100);t2.printT();Test t3;//就是调用类的无参数构造函数t3.printT();cout << "操作完毕" << endl;
}int main() {test01();return 0;
}
#endif

运行结果:

02构造函数分类

# if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Test {
public://test类的构造函数//在对象被创建的时候,用来初始化对象的函数Test(int x, int y) {m_x = x;m_y = y;name = (char *)malloc(100);strcpy(name, "zhangsan");}void printT(){cout << "x = " << m_x << "  y = " << m_y << endl;}//析构函数和构造函数都没有返回值,//析构函数没有形参~Test() {cout << "~Test 执行" << endl;if (name != NULL){free(name);name = NULL;cout << "free succ!" << endl;}}
private:int m_x;int m_y;char *name;
};
void test01() {//Test t1;  //报错 “Test” : 没有合适的默认构造函数可用Test t1(1, 2);  //ok
}
int main() {test01();return 0;
}#endif

运行结果:

03拷贝构造函数

# if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Test {
public://test类的构造函数//在对象被创建的时候,用来初始化对象的函数Test(){m_x = 0;m_y = 0;}Test(int x, int y) {m_x = x;m_y = y;}void printT(){cout << "x = " << m_x << "  y = " << m_y << endl;}
#if 0//显示的拷贝构造函数Test(const Test &another) {  //加const表示只读。要去初始化另一个值。自己本身不能被修改m_x = another.m_x;m_y = another.m_y;cout << "调用Test(const Test &another)拷贝 " << endl;}
#endif
#if 0//会有默认的拷贝构造函数 单纯的将一个类对象的数据成员变量赋值给本身Test(const Test &another) {  m_x = another.m_x;m_y = another.m_y;}
#endif   //=赋值操作符void operator=(const Test& another) {m_x = another.m_x;m_y = another.m_y;}
private:int m_x;int m_y;
};
void test01() {Test t1(100,200);Test t2(t1);  //提供默认拷贝构造函数t2.printT();//构造函数是对象初始化的时候调用Test t3 = t1;  //初始化t3时调用t3构造函数 依然是调用t3的拷贝构造函数t3.printT();Test t4;  //已经调用默认无参构造函数 初始化t4 = t1; //调用的不是t4拷贝构造函数,而是t4的赋值操作符函数
}
int main() {test01();return 0;
}#endif

运行结果:

04拷贝构造函数的应用场景

# if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Test {
public://test类的构造函数//在对象被创建的时候,用来初始化对象的函数Test() {cout << "Test()" << endl;m_x = 0;m_y = 0;}Test(int x, int y) {cout << "Test(int x, int y)" << endl;m_x = x;m_y = y;}void printT(){cout << "x = " << m_x << "  y = " << m_y << endl;}//显示的拷贝构造函数Test(const Test &another) {  //加const表示只读。要去初始化另一个值。自己本身不能被修改m_x = another.m_x;m_y = another.m_y;cout << "调用Test(const Test &another)拷贝 " << endl;}void operator=(const Test& another) {cout << "调用operator=(const Test& another) " << endl;m_x = another.m_x;m_y = another.m_y;}~Test() {cout << "~Test()...be done" << endl;}
private:int m_x;int m_y;
};
//析构函数的调用顺序 和构造相反:谁先构造,谁后析构  (栈结构)//场景1
void test01() {Test t1(10, 20);Test t2(t1);  //调用拷贝构造函数 等价于Test t2 = t1;
}
/*
运行结果:
Test(int x, int y)
调用Test(const Test &another)拷贝
~Test()...be done
~Test()...be done
*/
//场景2
void test02() {Test t1(10, 20);Test t2;t2 = t1;
}
/*
运行结果:
Test(int x, int y)
Test()
调用operator=(const Test& another)
~Test()...be done
~Test()...be done
*/
void func(Test t) {  //调用func时  Test t=t1; Test t的拷贝构造函数cout << "Func begin.." << endl;t.printT();cout << "Func end..." << endl;
}  //析构t
//场景3
void test03() {cout << "test03 begin.." << endl;Test t1(10, 20);func(t1);cout << "test03 end..." << endl;
} //析构t1
/*
运行结果:
test03 begin..
Test(int x, int y)
调用Test(const Test &another)拷贝
Func begin..
x = 10  y = 20
Func end...
~Test()...be done
test03 end...
~Test()...be done
*/
Test func2() {cout << "func2 begin..." << endl;Test temp(10, 20); temp.printT();cout << "func2 end..." << endl;return temp;  //会有 Test的匿名对象 匿名对象(temp)  temp去初始化匿名构造 匿名对象的拷贝构造
} //析构temp
//场景4
void test04() {cout << "test04 begin..." << endl;func2();  //返回一个匿名对象 当一个函数返回匿名对象时,//如果函数外部没有任何变量去接收它,这个匿名对象将不会再被使用//编译器会直接将这个匿名对象回收掉,而不是等待整个函数执行完毕后再回收//匿名对象被回收cout << "test04 end..." << endl;
}
/*
运行结果:
test04 begin...
func2 begin...
Test(int x, int y)
x = 10  y = 20
func2 end...
调用Test(const Test &another)拷贝
~Test()...be done
~Test()...be done
test04 end...
*///场景5
void test05() {cout << "test05 begin..." << endl;Test t1=func2();   //会不会触发t1的拷贝构造函数   t1.拷贝(匿名) //不会触发 将匿名对象转正为t1//给匿名对象 起了个名字就叫t1cout << "test05 end..." << endl;
}  //析构t1
/*
运行结果:
test05 begin...
func2 begin...
Test(int x, int y)
x = 10  y = 20
func2 end...
调用Test(const Test &another)拷贝
~Test()...be done
test05 end...
~Test()...be done
*///场景6
void test06() {cout << "test06 begin..." << endl;Test t1;  //t1已经被初始化t1 = func2();    //匿名对象赋值给t1,匿名对象并没有转正,所以即刻析构cout << "test06 end..." << endl;
}
/*
运行结果:
test06 begin...
Test()
func2 begin...
Test(int x, int y)
x = 10  y = 20
func2 end...
调用Test(const Test &another)拷贝
~Test()...be done
调用operator=(const Test& another)
~Test()...be done
test06 end...
~Test()...be done
*/
int main() {//test01();//test02();//test03();//test04();//test05();test06();return 0;
}#endif

05深拷贝与浅拷贝应用场景

防止内存泄漏(开辟的空间没有释放):导致内存爆掉 程序崩溃

防止释放同一块内存

当类的数据成员中有指针时,拷贝构造函数必须显式说明(为指针所存内存开辟空间)

同时析构函数 手动释放空间

# if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Teacher {
public:Teacher(int id, char *name) {cout << "Teacher(int id, char *name)" << endl;m_id = id;int len = strlen(name);m_name = (char*)malloc(len + 1);  //strlen长度计算不包括'\0' 所以此处加一strcpy(m_name, name);}void printT() {cout << "m_id:"<< m_id << " m_name : " << m_name << endl;}//默认拷贝构造函数Teacher(const Teacher &another) {m_id = another.m_id;m_name = another.m_name;  //指向同一块内存空间}~Teacher(){cout << "~Teacher()...." << endl;if (m_name != NULL) {free(m_name);}}
private:int m_id;//char m_name[64];  没有深拷贝 浅拷贝分解 因为此时m_name在栈上分配空间char *m_name;
};void test01() {Teacher t1(1, "zhangsan");t1.printT();Teacher t2(t1);  //调用t2的默认拷贝构造  程序崩溃t2.printT();
}  //t2析构 清空zhangsan所在空间 //t1析构时 也要清空zhangsan所在空间 然而已经清空 所以程序崩溃
int main()
{test01();return 0;
}
#endif

上述程序崩溃原因如下:

上述程序崩溃的主要原因就是默认拷贝构造函数的浅拷贝。所以使拷贝构造函数为深拷贝即可解决问题

程序如下:

# if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Teacher {
public:Teacher(int id, char *name) {cout << "Teacher(int id, char *name)" << endl;m_id = id;int len = strlen(name);m_name = (char*)malloc(len + 1);  //strlen长度计算不包括'\0' 所以此处加一strcpy(m_name, name);}void printT() {cout << "m_id:"<< m_id << " m_name : " << m_name << endl;}
#if 0//默认拷贝构造函数Teacher(const Teacher &another) {m_id = another.m_id;m_name = another.m_name;}
#endif//显式提供拷贝构造函数 完成深拷贝动作Teacher(const Teacher &another) {m_id = another.m_id;int len = strlen(another.m_name);m_name = (char *)malloc(len + 1);strcpy(m_name, another.m_name);}~Teacher(){cout << "~Teacher()...." << endl;if (m_name != NULL) {free(m_name);}}
private:int m_id;//char m_name[64];  没有深拷贝 浅拷贝分解 因为此时m_name在栈上分配空间char *m_name;
};void test01() {Teacher t1(1, "zhangsan");t1.printT();Teacher t2(t1);  //调用t2的默认拷贝构造  程序崩溃t2.printT();
}  //t2析构 清空zhangsan所在空间 //t1析构时 也要清空zhangsan所在空间 然而已经清空 所以程序崩溃
int main()
{test01();return 0;
}
#endif

运行结果:

不出错原因:

06构造函数的初始化列表

#include<iostream>
using namespace std;
class A
{
public:A(int a){cout << "A()..." << a << endl;m_a = a;}~A() {cout << "~A()" << endl;}void printA() {cout << "a = " << m_a << endl;}private:int m_a;
};
class B {
public:
#if 0B(int b, A &a1, A &a2) {//m_a1 = a1;  //赋值编译错误 //m_a2 = a2;   //m_a2(a2);  拷贝构造 编译错误  m_b = b;}
#endif/*构造函数的初始化列表  初始化对象时需要用到构造对象成员的顺序跟初始化列表的顺序无关而是跟成员对象的定义顺序有关*/B(A &a1, A &a2, int b) :m_a1(a1), m_a2(a2) {  //调用拷贝构造cout << "B(A&, A&, int)..." << endl;m_b = b;}B(int a1, int a2, int b) : m_a2(a2) ,m_a1(a1)  //调用有参构造{cout << "B(int, int, int)..." << endl;m_b = b;}void printB() {cout << "b = " << m_b << endl;m_a1.printA();m_a2.printA();}~B(){cout << "~B().." << endl;}
private:A m_a1;A m_a2;int m_b;
};void test01() {A a1(10),a2(100);B b(a1, a2, 1000);b.printB(); //b析构 b中A A析构 test01中a1 a2释放
}
/*
A()...10
A()...100
B(A&, A&, int)...
b = 1000
a = 10
a = 100
~B()..
~A()
~A()
~A()
~A()
*/
void test02() {B b(10, 20, 1000);b.printB();//b析构 b中A A析构 test01中a1 a2释放
}
/*
A()...10
A()...20
B(int, int, int)...
b = 1000
a = 10
a = 20
~B()..
~A()
~A()
*/
int main() {//test01();test02();return 0;
}

练习1(构造函数和析构函数的执行时间)

#if 0
#include<iostream>
using namespace std;
class   ABCD
{
public:ABCD(int a, int  b, int  c){_a = a;_b = b;_c = c;printf("ABCD()  construct,  a:%d,b:%d,c:%d \n", _a, _b, _c);}~ABCD(){printf("~ABCD()  construct,a:%d,b:%d,c:%d \n", _a, _b, _c);}int getA(){return   _a;}
private:int _a;int  _b;int  _c;
};
class   MyE
{
public:MyE() :abcd1(1, 2, 3), abcd2(4, 5, 6), m(100){cout << "MyD()" << endl;}~MyE(){cout << "~MyD()" << endl;}MyE(const    MyE &   obj) :abcd1(7, 8, 9), abcd2(10, 11, 12), m(100){printf("MyD(const  MyD &   obj)\n");}
public:ABCD abcd1;  //c++编译器不知道如何构造abc1ABCD   abcd2;const int m;
};
int doThing(MyE mye1)
{printf("doThing() mye1.abc1.a:%d \n", mye1.abcd1.getA());return 0;
}
int run()
{MyE    myE;doThing(myE);return 0;
}
/*
ABCD()  construct,      a:1,b:2,c:3
ABCD()  construct,      a:4,b:5,c:6
MyD()
ABCD()  construct,      a:7,b:8,c:9
ABCD()  construct,      a:10,b:11,c:12
MyD(const       MyD     &       obj)
doThing()       mye1.abc1.a:7
~MyD()
~ABCD() construct,a:10,b:11,c:12
~ABCD() construct,a:7,b:8,c:9
~MyD()
~ABCD() construct,a:4,b:5,c:6
~ABCD() construct,a:1,b:2,c:3
*/
int run2()
{printf("run2  start..\n");ABCD(400, 500, 600);   //临时对象的⽣命周期printf("run2    end\n");return 0;
}
/*
run2    start..
ABCD()  construct,      a:400,b:500,c:600
~ABCD() construct,a:400,b:500,c:600
run2    end
*/
int run3()
{printf("run2  start..\n");ABCD abcd=ABCD(100,   200,    300);printf("run2  end\n");return 0;
}
/*
run2    start..
ABCD()  construct,      a:100,b:200,c:300
run2    end
~ABCD() construct,a:100,b:200,c:300
*/
int main(void)
{//run();//run2();run3();return 0;
}
#endif

练习2:

#include<iostream>
using namespace std;
//构造中调⽤构造是危险的⾏为
class   MyTest
{
public:MyTest(int   a, int  b, int  c){_a = a;_b = b;_c = c;}MyTest(int  a, int  b){_a = a;_b = b;MyTest(a, b, 100);   //产⽣新的匿名对象}~MyTest(){printf("MyTest~:%d,   %d, %d\n", _a, _b, _c);}int    getC(){return   _c;}void    setC(int    val){_c = val;}
private:int _a;int  _b;int  _c;
};
int main()
{MyTest t1(1, 2);printf("c:%d\n", t1.getC()); //请问c的值是?return 0;
}
/*
MyTest~:1,      2,      100
c:-858993460
MyTest~:1,      2,      -858993460
*/

父类子类构造函数调用顺序

#include<iostream>
#include<string>
using namespace std;
class A
{
public:A() {std::cout << "cons A" << std::endl;}A(int i) {m_i = i;cout << "cons A with" << i << endl;}~A() {std::cout << "des A with" << m_i<< endl;}int m_i = 0;
};
# if 0
class B :public A {
public:B(){m_i = 3;cout << "cons B" << endl;}~B() {cout << "des B with" << m_i << endl;m_i = 4;}
private:A a1;A a2;
};
int main() {B b;return 0;
}
/*
cons A
cons A
cons A
cons B
des B with3
des A with0
des A with0
des A with4构造函数就是初始化数据成员的。所以现有构造函数的调用,再有数据成员的初始化
*/#endif# if 0
class B :public A {
public:B():a1(1),a2(2){m_i = 3;cout << "cons B" << endl;}~B() {cout << "des B with" << m_i << endl;m_i = 4;}
private:A a1;A a2;
};
int main() {B b;return 0;
}
/*
cons A
cons A with1
cons A with2
cons B
des B with3
des A with2
des A with1
des A with4
构造函数就是初始化数据成员的。所以现有构造函数的调用,再有数据成员的初始化
*/#endif# if 1
class B :public A {
public:B(){m_i = 3;cout << "cons B" << endl;}~B() {cout << "des B with" << m_i << endl;m_i = 4;}
};
int main() {B b;return 0;
}
/*
cons A
cons B
des B with3
des A with4
因为m_i 本身就是B从A继承而来,所以B中对m_i做更改,A也能感知到
*/#endif

C++基础05-类构造函数与析构函数相关推荐

  1. 派生类构造函数和析构函数的执行顺序

    派生类继承了基类的成员,实现了代码的重复利用,但基类的构造函数和析构函数不能被继承.如果在派生类中需要对新增加的成员进行初始化,则需要加入派生类的构造函数.同样派生类也需要添加析构函数来实现一些结束工 ...

  2. C++类构造函数与析构函数

    C++类的构造函数和析构函数 一.构造函数 构造函数在类的对象被创建时,自己调用,不可以显式调用.通常用构造函数来做一些初始化的工作. 构造函数又分为两类: 1. 无参数的构造函数2. 带参数的构造函 ...

  3. 详解派生类构造函数与析构函数

    1.派生类构造函数: 派生类不能继承基类的构造函数,必须自己定义构造函数进行新增数据成员初始化工作,如果想同时初始化基类数据成员,必须调用基类构造函数. (1)简单派生类构造函数: 1 #includ ...

  4. c++中的派生类构造函数和析构函数

    1.派生类构造函数 派生类的构造函数必须自己定义,因为要对新增数据成员进行初始化.如果想要同时初始化基类的数据成员,必须调用基类的构造函数. 创建一个派生类对象的时候,首先调用基类的构造函数,再调用派 ...

  5. C++ 类(构造函数和析构函数)

    文章概述 构造函数和析构函数的由来? 构造函数和析构函数的基本语法 C++编译器构造析构方案 PK 对象显示初始化方案 构造函数的分类以及调用 默认的构造函数 构造函数调用规则 构造函数和析构函数的总 ...

  6. C++经验(四)-- 基类构造函数和析构函数中调用virtual虚函数?

    class Base {public:Base();virtual void oneFunction() = 0;... };Base::Base() {...oneFunction(); }clas ...

  7. 简单的派生类构造函数C++

    **#include<iostream> #include <string> using namespace std; class Student{ public:Studen ...

  8. C++学习——构造函数,析构函数与虚函数关系

    文章目录 1.构造函数,析构函数可以为虚函数吗? 2.析构函数和构造函数的作用? 3.构造函数和析构函数调用顺序? 4.类什么时候会调用析构函数? 1.构造函数,析构函数可以为虚函数吗? 构造函数不可 ...

  9. C++基础第三章(使用类和对象)上篇(类的构造函数和析构函数)

    利用构造函数对类对象初始化 在类内如果数据成员是公有的则可以在类内直接进行初始化 #include<iostream> using namespace std; class Time {p ...

  10. 类继承中的构造函数与析构函数

    构造函数初始化列表 子类的初始化列表,只能对子类的成员变量进行初始化 class Base{ public:int x; };class Derived : public Base { public: ...

最新文章

  1. 华为云免费体验 怎么使用_华为云Classroom免费向全国高校开放,云端学习更高效...
  2. day16——函数式编程和内置函数
  3. Error: vue-loader requires @vue/compiler-sfc to be
  4. 基于农业物联网的感知数据获取和可视化系统
  5. 如何建立java ssm工程_如何搭建一个ssm项目
  6. win10打开计算机黑屏怎么办,教你如何解决win10电脑开机黑屏的问题
  7. c语言编写单片机技巧
  8. Go Slice 使用中的小陷阱
  9. Spring3.0包描述
  10. 字体设计灵感|浓墨重彩!代表“墨”字设计案例
  11. 谈谈html5存储之IndexdDB
  12. 有多少人欠网贷,往后的日子你打算怎么过?
  13. javaScript中的Object类型
  14. 【SQL server】数据库的彻底卸载
  15. java软件开发必读15本书籍
  16. 微信小程序在聊天中如何插入表情?
  17. 【offer谈判】如何做一朵盛世白莲花,让企业愿意为你花大价钱!
  18. 【python】OpenCV—RGB, Rectangle, Circle, SS(1)
  19. STM32多路红外发送
  20. 计算机表格常用根式,excel怎么建立常用根式_在excel中怎样开根号�9�3

热门文章

  1. Java 8 Stream 流用法及语法
  2. git的clone命令出现fatal:unable to access ‘https://github.comXXXXXXX“:OpenSSL SSL_read:connection was errn
  3. boost互斥锁_boost锁使用总结
  4. 计算机考试internet应用好考吗,2015年职称计算机考试XP好考还是internet应用好考...
  5. 一体化住户调查_曲麻莱县2020年城乡一体化住户调查表彰会暨年报部署会
  6. nginx 上传 文件超时设置_nginx限制上传大小和超时时间设置说明/php限制上传大小...
  7. app每秒并发数_性能测试连载 (38) jmeter 线程数与性能测试的负载模式
  8. thinkphp三级分销小程序源码_山东谷道微信小程序商城源码带后台 公众号平台三级分销系统...
  9. 计算机中丢失msc,mscvr120.dll32位/64位版_修复计算机中丢失msvcr120.dll
  10. alsa的动态库安装在哪里_Linux链接库一(动态库,静态库,库放在什么路径下)...