c++-构造函数
2019-12-21 16:01:23来源:博客园 阅读 ()
c++-构造函数
构造函数
- 构造和析构概念语法
- 构造函数的分类
- 有参构造函数3种调用方法
- 拷贝构造函数4种调用时机
- 场景1和2:A a(b); A a = b;
- 场景3:形参是一个元素,实参传递给形参
- 场景4:函数返回值返回一个元素,匿名对象
- 匿名对象的去和留
- 对象的初始化 和 对象的=操作 是两个不同的概念
- 构造和析构
- 构造和析构概念语法
- 构造函数的分类
- 有参构造函数3种调用方法
- 拷贝构造函数4种调用时机
- 场景1和2:A a(b); A a = b;
- 场景3:形参是一个元素,实参传递给形参
- 场景4:函数返回值返回一个元素,匿名对象
- 匿名对象的去和留
- 对象的初始化 和 对象的=操作 是两个不同的概念
- 构造函数调用规则研究(写了构造函数则必须调用)
- 多个对象的构造 构造函数初始化列表
- 构造函数和析构函数的调用顺序(先组合对象的构造、自己构造;析构和构造相反)
- 深拷贝和浅拷贝
- 问题抛出 显示的编写拷贝构造函数
- 默认的=号操作 也是浅拷贝,解决方案重载=操作符
- 总结:C++编译给提供的默认的拷贝构造和=操作都是浅拷贝
- 构造和析构综合练习
- 匿名对象:直接调用构造函数
- 匿名对象:构造中调用构造
- 构造函数调用规则研究(写了构造函数则必须调用)
- 多个对象的构造 构造函数初始化列表
- 构造函数和析构函数的调用顺序(先组合对象的构造、自己构造;析构和构造相反)
- 深拷贝和浅拷贝
- 问题抛出 显示的编写拷贝构造函数
- 默认的=号操作 也是浅拷贝,解决方案重载=操作符
- 总结:C++编译给提供的默认的拷贝构造和=操作都是浅拷贝
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
#if 0
void init(int x, int y)
{
m_x = x;
m_y = y;
}
#endif
//test类的构造函数
//在对象被创建的时候,用来初始化对象的函数
Test()//无参数的构造函数
{
m_x = 0;
m_y = 0;
}
Test(int x, int y)
{
m_x = x;
m_y = y;
// name = (char*)malloc(100);
strcpy(name, "zhang3");
}
Test(int x)
{
m_x = x;
m_y = 0;
}
void printT()
{
cout << "x = " << m_x << " y = " << m_y << endl;
}
//析构函数和构造函数都没有返回值,
//析构函数没有形参
~Test() {
cout << "~Test()...." << endl;
if (name != NULL) {
// free(name);
cout << "free succ!" << endl;
}
}
private:
int m_x;
int m_y;
char *name;
};
void test1()
{
Test t1(10, 20);
t1.printT();
//在一个对象临死之前,要自定调用析构函数
}
int main(void)
{
#if 0
Test t1(10, 20);
t1.printT();
//t1.init(10, 20);
Test t2(100);
t2.printT();
Test t3;//就是调用类的无参数构造函数
t3.printT();
#endif
test1();
return 0;
}
拷贝构造函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
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 1
//显示的拷贝构造函数
Test(const Test &another)
{
cout << "Test(const Test &)..." << endl;
m_x = another.m_x;
m_y = another.m_y;
}
#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;
};
int main(void)
{
Test t1(100, 200);
Test t2(t1);
t2.printT();
//构造函数是对象初始化的时候调用
Test t3; //依然是初始化t3的时候调用t3构造函数,依然是调用t3的拷贝构造函数
t3 = t1; //调用的不是t3拷贝构造函数,而是t3的赋值操作符函数
return 0;
}
默认的构造函数和解析构造函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
//默认的无参构造函数
#if 0
Test()
{
}
#endif
//显示提供一个有参数的构造函数,默认的构造函数就不复存在
Test(int x, int y)
{
m_x = x;
m_y = y;
}
Test() {
m_x = 0;
m_y = 0;
}
void printT()
{
cout << "x = " << m_x << " y = " << m_y << endl;
}
//默认的析构函数
#if 0
~Test()
{
}
#endif
~Test() {
cout << "~Test()..." << endl;
}
private:
int m_x;
int m_y;
};
int main(void)
{
Test t1;//调用Test无参构造
t1.printT();
return 0;
}
默认的拷贝构造函数
- 类中 会有个默认的无参构造函数:
当没有任何显示的构造函数(显示的无参构,显示有参,显示拷贝构造) 的时候,默认无参构造函数就会出现。
会有默认的拷贝构造函数:
-->当没有 显示的拷贝构造 * 的函数,默认的拷贝构造就会出现。会有默认的析构函数
--> 当没有显示的析构函数的时候, 默认的析构函数就会出现
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A
{
public:
#if 0
A()
{
}
#endif
#if 0
A(const A &another)
{
m_a = another.m_a;
m_b = another.m_b;
}
#endif
A()
{
}
A(int a, int b)
{
}
#if 0
~A()
{
}
#endif
~A()
{
cout << "~A()" << endl;
}
private:
int m_a;
int m_b;
};
//类中 会有个默认的无参构造函数: 、
// -->当没有任何***显示的构造函数(显示的无参构,显示有参,显示拷贝构造)*** 的时候,默认无参构造函数就会出现。
// 会有默认的拷贝构造函数:
// -->当没有 **显示的拷贝构造 *** 的函数,默认的拷贝构造就会出现。
// 会有默认的析构函数
// --> 当没有***显示的析构函数***的时候, 默认的析构函数就会出现。
int main(void)
{
A a;
A a1(a);
return 0;
}
拷贝构造函数的应用场景
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
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;
}
Test(const Test & another)
{
cout << "Test(const Test &)..." << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void operator=(const Test &another)
{
cout << "operatoer = (const Test &)" << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void printT() {
cout << "x = " << m_x << ", m_y = " << m_y << endl;
}
~Test() {
cout << "~Test()..." << endl;
}
private:
int m_x;
int m_y;
};
//析构函数调用的顺序, 跟构造相反, 谁先构造的,谁后析构。
//场景1
void test1()
{
Test t1(10, 20);
Test t2(t1);//Test t2 = t1;
}
//场景2
void test2()
{
Test t1(10, 20);
Test t2;
t2 = t1;//=操作符
}
void func(Test t)//Test t = t1; //Test t 的拷贝构造函数
{
cout << "func begin..." << endl;
t.printT();
cout << "func end..." << endl;
}
//场景3
void test3()
{
cout << "test3 begin..." << endl;
Test t1(10, 20);
func(t1);
cout << "test3 end..." << endl;
}
//场景4
Test func2()
{
cout << "func2 begin..." << endl;
Test temp(10, 20);
temp.printT();
cout << "func2 end..." << endl;
return temp;
}//匿名的对象 = temp 匿名对象.拷贝构造(temp)
void test4()
{
cout << "test4 being.. " << endl;
func2();// 返回一个匿名对象。 当一个函数返回一个匿名对象的时候,函数外部没有任何
//变量去接收它, 这个匿名对象将不会再被使用,(找不到), 编译会直接将个这个匿名对象
//回收掉,而不是等待整改函数执行完毕再回收.
//匿名对象就被回收。
cout << "test4 end" << endl;
}
void test5()
{
cout << "test 5begin.. " << endl;
Test t1 = func2(); //会不会触发t1拷贝构造来 t1.拷贝(匿名)?
//并不会触发t1拷贝,而是 将匿名对象转正 t1,
//把这个匿名对象 起了名字就叫t1.
cout << "test 5 end.." << endl;
}
//场景6
void test6()
{
cout << "test6 begin..." << endl;
Test t1;//t1已经被初始化了。
t1 = func2(); //t1已经被初始化了,所以func2返回的匿名对象不会再次转正,而依然是匿名对象。
//所以t1会调用等号操作符,t1.operator=(匿名对象), 然后编译器会立刻回收掉匿名对象
t1.printT();
cout << "test6 end.." << endl;
}
int main(void)
{
//test1();
//test2();
//test3();
//test4();
//test5();
test6();
return 0;
}
深拷贝和浅拷贝
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
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;
}
Test(const Test & another)
{
cout << "Test(const Test &)..." << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void operator=(const Test &another)
{
cout << "operatoer = (const Test &)" << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void printT() {
cout << "x = " << m_x << ", m_y = " << m_y << endl;
}
~Test() {
cout << "~Test()..." << endl;
}
private:
int m_x;
int m_y;
};
//析构函数调用的顺序, 跟构造相反, 谁先构造的,谁后析构。
//场景1
void test1()
{
Test t1(10, 20);
Test t2(t1);//Test t2 = t1;
}
//场景2
void test2()
{
Test t1(10, 20);
Test t2;
t2 = t1;//=操作符
}
void func(Test t)//Test t = t1; //Test t 的拷贝构造函数
{
cout << "func begin..." << endl;
t.printT();
cout << "func end..." << endl;
}
//场景3
void test3()
{
cout << "test3 begin..." << endl;
Test t1(10, 20);
func(t1);
cout << "test3 end..." << endl;
}
//场景4
Test func2()
{
cout << "func2 begin..." << endl;
Test temp(10, 20);
temp.printT();
cout << "func2 end..." << endl;
return temp;
}//匿名的对象 = temp 匿名对象.拷贝构造(temp)
void test4()
{
cout << "test4 being.. " << endl;
func2();// 返回一个匿名对象。 当一个函数返回一个匿名对象的时候,函数外部没有任何
//变量去接收它, 这个匿名对象将不会再被使用,(找不到), 编译会直接将个这个匿名对象
//回收掉,而不是等待整改函数执行完毕再回收.
//匿名对象就被回收。
cout << "test4 end" << endl;
}
void test5()
{
cout << "test 5begin.. " << endl;
Test t1 = func2(); //会不会触发t1拷贝构造来 t1.拷贝(匿名)?
//并不会触发t1拷贝,而是 将匿名对象转正 t1,
//把这个匿名对象 起了名字就叫t1.
cout << "test 5 end.." << endl;
}
//场景6
void test6()
{
cout << "test6 begin..." << endl;
Test t1;//t1已经被初始化了。
t1 = func2(); //t1已经被初始化了,所以func2返回的匿名对象不会再次转正,而依然是匿名对象。
//所以t1会调用等号操作符,t1.operator=(匿名对象), 然后编译器会立刻回收掉匿名对象
t1.printT();
cout << "test6 end.." << endl;
}
int main(void)
{
//test1();
//test2();
//test3();
//test4();
//test5();
test6();
return 0;
}
构造函数的初始化列表
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
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;
}
Test(const Test & another)
{
cout << "Test(const Test &)..." << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void operator=(const Test &another)
{
cout << "operatoer = (const Test &)" << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void printT() {
cout << "x = " << m_x << ", m_y = " << m_y << endl;
}
~Test() {
cout << "~Test()..." << endl;
}
private:
int m_x;
int m_y;
};
//析构函数调用的顺序, 跟构造相反, 谁先构造的,谁后析构。
//场景1
void test1()
{
Test t1(10, 20);
Test t2(t1);//Test t2 = t1;
}
//场景2
void test2()
{
Test t1(10, 20);
Test t2;
t2 = t1;//=操作符
}
void func(Test t)//Test t = t1; //Test t 的拷贝构造函数
{
cout << "func begin..." << endl;
t.printT();
cout << "func end..." << endl;
}
//场景3
void test3()
{
cout << "test3 begin..." << endl;
Test t1(10, 20);
func(t1);
cout << "test3 end..." << endl;
}
//场景4
Test func2()
{
cout << "func2 begin..." << endl;
Test temp(10, 20);
temp.printT();
cout << "func2 end..." << endl;
return temp;
}//匿名的对象 = temp 匿名对象.拷贝构造(temp)
void test4()
{
cout << "test4 being.. " << endl;
func2();// 返回一个匿名对象。 当一个函数返回一个匿名对象的时候,函数外部没有任何
//变量去接收它, 这个匿名对象将不会再被使用,(找不到), 编译会直接将个这个匿名对象
//回收掉,而不是等待整改函数执行完毕再回收.
//匿名对象就被回收。
cout << "test4 end" << endl;
}
void test5()
{
cout << "test 5begin.. " << endl;
Test t1 = func2(); //会不会触发t1拷贝构造来 t1.拷贝(匿名)?
//并不会触发t1拷贝,而是 将匿名对象转正 t1,
//把这个匿名对象 起了名字就叫t1.
cout << "test 5 end.." << endl;
}
//场景6
void test6()
{
cout << "test6 begin..." << endl;
Test t1;//t1已经被初始化了。
t1 = func2(); //t1已经被初始化了,所以func2返回的匿名对象不会再次转正,而依然是匿名对象。
//所以t1会调用等号操作符,t1.operator=(匿名对象), 然后编译器会立刻回收掉匿名对象
t1.printT();
cout << "test6 end.." << endl;
}
int main(void)
{
//test1();
//test2();
//test3();
//test4();
//test5();
test6();
return 0;
}
原文链接:https://www.cnblogs.com/ygjzs/p/12076497.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- C++ 转换函数搭配友元函数 2020-06-10
- C++ rand函数 2020-06-10
- C++ 友元函数 2020-06-10
- C++ const成员函数 2020-06-03
- C++ 析构函数 2020-06-03
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash