C++基础05-类构造函数与析构函数

总结:

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567892.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP网站配置项,Thinkphp5通用网站后台配置项的动态添加及更新

一、引入无论平时我们自己制作&#xff0c;还是浏览别人的网站&#xff0c;它都具有其相应的一些共用的、通用的属性&#xff0c;比如&#xff1a;网站的名字&#xff0c;关键字、备案号、分页数量、是否开启缓存等信息。一些网站可能将配置项写死在后台&#xff0c;无法动态更…

C++基础06-类与对象之new和malloc

1、C和C动态分配内存区别&#xff1a; 在C语言中是利用库函数malloc和free来分配和撤销内存空间的。 C提供了较简便而功能较强的运算符new和delete来取代 malloc和free函数。 new和delete是运算符&#xff0c;不是函数&#xff0c;因此执行效率高。 2、new和delete的用法 &l…

php获取数组中的全部可以吗,php获取数组中所有值的方法

php的数组操作函数array_values 可以提取一个数组中所有元素值&#xff0c;具体的使用方法&#xff0c;可以参考下面的教程。array_values() 函数的作用是返回数组中所有元素的值&#xff0c;使用起来非常简单&#xff0c;只有一个必选参数&#xff0c;就可以返回一个包含给定数…

C++基础07-类之静态成员变量和成员函数

总结&#xff1a; 1、静态数据成员和静态成员函数属于整个类而不是某个对象 即使没有定义对象&#xff0c;静态成员也是存在的 2、static 成员类外存储,求类大小,并不包含在内。 &#xff08;因为存储在全局区&#xff0c;而类一般存储在栈区&#xff09; 3、静态数据成员在…

oracle 查询cpu 100%,Oracle 11g中查询CPU占有率高的SQL

oracle版本&#xff1a;oracle11g背景&#xff1a;今天在Linux中的oracle服务上&#xff0c;运用top命令发现许多进程的CPU占有率是100%。操作步骤&#xff1a;以进程PID:7851为例执行以下语句&#xff1a;方法一&#xff1a;(1)通过PID&#xff0c;查得相对应的系统进程对应的…

C++基础08-this指针-const修饰成员函数-函数返回引用/值

一、this指针 1、C类对象中的成员变量和成员函数是分开存储的。C语言中的内存四区模型仍然有效&#xff01; 2、C中类的普通成员函数都隐式包含一个指向当前对象的this指针。 3、静态成员函数、成员变量属于类 4、静态成员函数与普通成员函数的区别 静态成员函数不包含指…

oracle 10046详解,Oracle 10046事件详解

10046事件说明10046事件是Oracle提供的内部事件&#xff0c;是对SQL_TRACE的增强.10046事件可以设置以下四个级别:1 - 启用标准的SQL_TRACE功能,等价于sql_trace4 - Level 1 加上绑定值(bind values)8 - Level 1 等待事件跟踪12 - Level 1 Level 4 Level 8类似sql_trace&…

C++基础09-货物售卖和MyArray实现

1、货物出货与进货 #if 0 #include<iostream> using namespace std; /* 某商店经销一种货物。货物购进和卖出时以箱为单位。各箱 的重量不一样&#xff0c;因此商店需要记录目前库存的总重量&#xff0c;现在用 C模拟商店货物购进和卖出的情况 */ class Goods { public:…

oracle+导入emp,Oracle数据库导入导出emp文件

首先询问对方数据库的表空间名称和大小&#xff0c;然后在你的oracle中建立相应表空间&#xff0c;最后使用命令导入、导出数据。补充&#xff1a;1.要新建一个数据库&#xff1b;Oracle数据导入导出imp/exp就相当于oracle数据还原与备份。exp命令可以把数据从远程数据库服务器…

C++基础10-类和对象之友元函数

采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员, 这时可以将这些函数定义为该 函数的友元函数。除了友元函…

linux进程号为一,一步步探究linux进程中的用户ID

转载请注明来源chengyaogen.blog.chinaunix.net一、进程与权限A.进程时Linux/Unix操作系统中最重要的抽象之一B.进程是一个处于执行期的程序(目标代码存储在某种介质上)A process is a program(object code stored on some media) in the midst ofexecution.而进…

C++基础11-类和对象之操作符重载1

总结&#xff1a; 1、运算符重载的本质是函数重载 2、运算符重载可分为成员函数重载和全局函数重载(差一个参数) 3、运算符重载函数的参数至少有一个是类对象&#xff08;或类对象的引用&#xff09; 4、不可以被重载的操作符有&#xff1a;成员选择符(.) 成员对象选择符(.*) …

linux下搜狗安装目录,Linux安装搜狗输入法

本系统使用Ubuntu16.04LTS安装中文输入法Ubuntu17.04中支持IBUS&#xff0c;fcitx等输入法框架。分别介绍两种框架下的中文输入法安装&#xff1a;1.IBUS框架下的拼音输入法1.1在Ubuntu Software搜索“pinyin”&#xff0c;安装列表中第一个&#xff1b;1.2在系统设置-Language…

在Linux系统下实现进程,Linux进程学习(一)之Linux进程的基本知识和实现

最近一周学习了Linux 进程编程的知识&#xff0c;现对其总结如下。在第一部分中我们先对进程的基本概念以及在Linux 中是如何来现实进程的进行介绍Tiger-John说明 &#xff1a;许多人在学习中只注重如何编程&#xff0c;却忘了注重原理,不去深究其基本原理。其实操作系统的原理…

C++基础11-类和对象之操作符重载2

总结&#xff1a; 1、等号操作符重载和拷贝构造函数重载一般用在数据成员中需要单独在堆区开辟内存时(指针) 2、new&#xff0c;delete重载内部还是使用malloc和free 3、逗号表达式(,)、或者(||)&#xff0c;且(&&)&#xff0c;条件表达式(?:)具有短路功能。 但…

linux照片备份软件,Linux、Unix上5个惊艳开源备份软件

Linux和类Unix系统上5个惊艳的开源备份软件&#xff1a;Bacula、Amanda、Backupninja、Backuppc和UrBackup&#xff0c;这些都是既可以使用在Linux上也可以使用在Unix上面&#xff0c;他们的优点就是性能稳定&#xff0c;使用灵活。一个好的备份计划是非常必要的&#xff0c;这…

C/C++混淆点-运算符短路

主要内容如下&#xff1a; 按照C/C标准 1.9.18 节的说明&#xff0c;||,&&,?:三目运算符和逗号运算符采用短路运算&#xff0c;第一个表达式之后作为一个运算顺序点。 1 a && b; 2 a || b; 3 a ? b : c; 4 a, b; 短路运算仅对内置的行为有效&#xff0c;如…

C++基础12-类和对象之操作符重载-string练习

总结&#xff1a; 1、等号操作符重载注意事项&#xff1a; &#xff08;1&#xff09;防止自身赋值 &#xff08;2&#xff09;先将自身的额外开辟的空间回收掉 &#xff08;3&#xff09;执行深拷贝 2、注意函数的返回引用或者元素&#xff1a;如果需要连续使用 …

linux中类似findfirst的函数,findfirst函数的用法

函数名称: findfirst函数原型: int findfirst(char *fname,struct ffblk *ptr,int attrib)函数功能: 寻找与fname相匹配的第一个文件名称函数返回:参数说明: ptr-保存查找到的文件信息所属文件: #include #include int main(){struct ffblk ffblk;int d…

C/C++混淆点-逗号运算符

在C中&#xff0c;逗号是很常用的。作为一个运算符它虽然不常用&#xff0c;但我们也应该学会它的用法。 1.如&#xff1a;a3*4,4*5,5*6; 由于“”的优先级高于“&#xff0c;”&#xff0c;所以程序从左向右运行&#xff0c;即先运行a3*4。之后的4*5&#xff0c;5*6仅仅运行&a…