精华内容
下载资源
问答
  •  只有一,默认构造函数。(不带参数的构造函数) 答: 两:  1.不带任何参数的构造函数。比如 Example();如果用户没有定义任何构造函数,则编译器会默认提供这个构造函数。  2.带默认值得构造函数。...

    答:


            只有一种,默认构造函数。(不带参数的构造函数)

    答:

    两种:

            1.不带有任何参数的构造函数。比如 Example();如果用户没有定义任何构造函数,则编译器会默认提供这个构造函数。
            2.带有默认值得构造函数。比如Example(int a = 23);

    展开全文
  • c++中调用无参数构造函数 #include <iostream> using namespace std; class A { public: //无参构造函数 A() { cout << "调用无参构造函数" << endl; } ~A() { cout << "调用析构...

    c++中调用无参数构造函数

    #include <iostream>
    using namespace std;
     
    class A {
    public:
    	//无参构造函数
    	A() {
    		cout << "调用无参构造函数" << endl;
    	}
    	~A() {
    		cout << "调用析构函数" << endl;
    	}
    };
    void obj() {
    	//定义类A的对象,并调用无参构造函数
    	A a;
    }
     
    int main()
    {
    	obj();
        cout << "Hello World!\n";
    	system("pause");
    }
    

    c++中,调用有参数构造函数有三种方式:

    #include<iostream>
    using namespace std;
    class Test {
    private:
    	int a;
    	int b;
    public:
    	//定义带参数的构造函数
    	Test(int a) {
    		cout << "a  = " << a <<endl;
    	}
    	Test(int a, int b) {
    		cout << "a = " << a << "  b = " << b << endl;
    	}
     
    };
    int main() {
    	// 1、 括号法
    	Test t1(10);
    	Test t2(10, 20);
    	// 2. 等号法
    	Test t3 = (1, 2,3);
    	// 3. 构造函数法, 手动直接调用构造函数
    	Test t4 = Test(10, 20);
    	system("pause");
    }
    

    在这里插入图片描述
    本文转载链接:https://blog.csdn.net/qq_20880939/article/details/103064425

    展开全文
  • C++构造函数的集中使用时机Test测试类使用无参数构造函数使用参数构造函数使用copy构造函数功能快捷键合理的创建标题,助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你...

    Test测试类以及所用全局函数

    class Test
    {
    public:
    	Test()
    	{
    		m_a = 0;
    		m_b = 0;
    		cout << "我是无参构造函数" << endl;
    	}
    	Test(int a)
    	{
    		m_a = a;
    		m_b = 0;
    	}
    	Test(int a, int b) //有三种调用方法;
    	{
    		m_a = a;
    		m_b = b;
    		cout << "我是有参数构造函数" << endl;
    	}
    	Test(const Test & obj)//用一个对象去初始化另一个对象;
    	{
    		cout << "我是赋值构造函数" << endl;
    	}
    protected:
    private:
    	int m_a;
    	int m_b;
    };
    void f(Test p)
    {
    	cout << "Hello world" << endl;
    }
    Test g()
    {
    	Test a(2);
    	return a;
    }
    

    使用无参数构造函数

    void main()
    {
    	Test t1;
    	system("pause");
    }
    

    在创建t1对象是,c++编译器隐式的调用了无参构造函数。

    使用有参数构造函数

    void main()
    {
    	Test t2(1, 2); 
    	Test t3 = (3, 4);
    	Test t4 = 5;
    	system("pause");
    }
    

    t2对象在初始化时c++编译器会调用有两个参数的构造函数,t3对象对象由于后边的逗号表达式的值为4,所以C++编译器会调用有一个参数的构造函数,t4对象和t3对象道理相同。

    使用copy构造函数

    void main()
    {
    	Test t1(1, 2);
    	Test t5(t1);
    	Test t6 = t1;
    	f(t1);
    	Test t7 = g();
    	t7 = g();
    	system("pause");
    }
    

    t5对象的初始化时c++编译器会调用copy构造函数,t6对象是 = 运算符重载,和t5对象类似,使用 f(t1) 函数时会创建一个p对象,这时c++编译器会调用copy构造函数,t7对象在初始化时会调用 g() 函数,g() 函数会创建一个局部对象a,在函数结束时需要将a对象返回,这是c++编译器会创立一个匿名对象来保存a的数据,如 Test t7 = g() 这一调用方式,c++编译器会直接把匿名对象转正,即给匿名对象命名为t7,而 t7 = g() 这种调用方法会先将匿名对象的数据赋值给t7对象然后匿名对象会被析构。

    展开全文
  • 【c++类的构造函数几种写法及问题 一、构造函数的定义 类通过一个或几个特殊的与类同名的成员函数来控制其对象的初始化过程,这些函数叫构造函数构造函数的任务是初始化类对象的数据成员,无论何时只要类的对象...

    【c++类的构造函数】几种写法及问题

    一、构造函数的定义

    类通过一个或几个特殊的与类同名的成员函数来控制其对象的初始化过程,这些函数叫构造函数。构造函数的任务是初始化类对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数。

    该函数无返回类型(是 “ 无 ” 而不是 “ 空 ” (void))。但是该函数有返回值(这个类的对象)。并且一个对象也只能在被创建的时候调用构造函数,即一个对象只能调用一次构造函数。
    (构造函数就相当于一个人的出生,析构函数就是一个人的终结。)

    特别的,一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载

    二、构造函数的分类

    1、默认构造函数

    默认构造函数就是在调用时不需要显示地传入实参的构造函数。

    分为 无参数默认构造函数带缺省参数的默认构造函数

    例如:
    现在假设有一个类Time,该类有三个公有成员 Hour,Minute,Second。
    将该类定义在“Time.h”的头文件里。再建一个“Time.cpp”用来放Time类的函数定义。最后建“MyProject.cpp”用来放主函数。

    1.无参数默认构造函数:
    Time.h”:
    在这里插入图片描述
    在头文件的函数声明中只有与类名相同的函数名,无任何参数。

    "Time.cpp":
    在这里插入图片描述
    初始化列表法:

    	Time::Time() Hour(1),Minute(1),Second(59){}
    

    需要在函数定义中定义出具体的数值。(如果程序员没有定义任何构造函数,编译器会自动定义一个跟这个差不多类型的 / / 但看似是定义了个 啥也没有 )

    也可以只在头文件中:

    Time(){}
    

    以 Student(){} 这样的方式来声明无参数构造函数,会带来一个问题,就是使得 其不再是 POD 类型,因此可能让编译器失去对这样的数据类型的优化功能。这是我们不希望看到的。因此最好使用 = default来修饰默认构造函数。
    即:

    Time() = default;
    

    MyProject.cpp”:
    在这里插入图片描述
    使用无参构造函数创建对象时,不应在对象名后面加上括号,否则会产生编译警告“warning C4930: “Sample s(void)”: 未调用原型函数(是否是有意用变量定义的?)”。

    也就是不能写成:

    int main()
    {
        Time mytime();
    }
    

    2.带缺省参数的默认构造函数:

    Time.h”:
    在这里插入图片描述
    定义缺省默认构造函数即为 定义所有参数都有默认值的函数。

    "Time.cpp":
    在这里插入图片描述
    由于在头文件声明中已经初始化过了,所以不需要赋值。

    MyProject.cpp”:
    在这里插入图片描述
    同无参默认构造函数。(不能只加括号)
    但缺省默认构造函数可以在括号中加入值,则初始值就是括号中的值。

    int main()
    {
    	Time mytime(1,2,3); 							 //最终初始值即为1 2 3
    }
    

    注意

    1、以上两种默认构造函数不能同时出现。同时存在时,编译器会产生二义性,从而生成编译错误。

    // error C2668: 对重载函数的调用不明确

    2、只要定义了构造函数后,程序就不会自行提供默认构造函数了。

    如果你定义了一个有参的构造函数,为了保证正确性,系统不会创建无参构造函数,这时候,如果你还想允许无参构造,程序员需要自己手动再声明一个。
    一般选择Time();这种形式的默认构造函数。

    3、编译器在什么情况下会生成默认构造函数?

    有一句很经典的话可以用来回答这个问题:

    惟有默认构造函数”被编译器需要“的时候,编译器才会生成默认构造函数。

    那我们只需知道什么时候“被编译器需要”,就可以知道什么情况下会生成默认构造函数了。下面几种情况下,编译需要生成默认构造函数:

    1. 当该类的类对象数据成员有默认构造函数时。
    2. 当该类的基类有默认构造函数时。
    3. 当该类的基类为虚基类时。
    4. 当该类有虚函数时。

    2、一般构造函数

    这里主要举几个特例。 // 例子中加上一个成员函数void print();

    1.三个参数的构造函数:(但在函数声明中有默认参数)

    Time.h”:

    #ifndef __MYTIME__
    #define __MYTIME__
    #include<iostream>
    using namespace std;
    
    class Time {
    public:
    	int Hour;
    	int Minute;
    	int Second;
    
    	Time(int tmphour,int tmpmin,int tmpsec=6);	 //在这里提供默认参数(所有成员变量全提供就是缺省默认)
    	
    	void print()
    	{
    		cout << Hour << endl;  
    		cout << Minute << endl; 
    		cout << Second << endl; 
    	}
    };
    #endif
    

    "Time.cpp":

    #include<iostream>
    #include "Time.h"
    
    using namespace std;
    
    Time::Time(int tmphour, int tmpmin, int tmpsec)
    {
    	Hour = tmphour;  
    	Minute = tmpmin;
    	Second = tmpsec;
    }
    

    MyProject.cpp”:

    #include <iostream>
    #include <vector>
    
    #include "Time.h"
    
    using namespace std;   
    
    int main()
    {
    	Time mytime(1,2,3);						//这样输出还是1 2 3
    											//把3去掉就是1 2 6,如:
    											//Time mytime(1,2);
    
    	mytime.print();
    	
    	return 0;
    }
    

    可以任意含有任意个默认参数。

    2.两个参数的构造函数:

    Time.h”:

    #ifndef __MYTIME__
    #define __MYTIME__
    #include<iostream>
    
    
    using namespace std;
    class Time {
    public:
    	int Hour;
    	int Minute;
    	int Second;
    
    	Time(int tmphour,int tmpmin);					//只有两个参数
    	
    	void print()
    	{
    		cout << Hour << endl;  
    		cout << Minute << endl; 
    		cout << Second << endl; 
    	}
    };
    #endif
    

    "Time.cpp":

    #include<iostream>
    #include "Time.h"
    
    using namespace std;
    
    Time::Time(int tmphour, int tmpmin)
    {
    	Hour = tmphour;  
    	Minute = tmpmin;
    	Second = 59;                  		//这里初始化(这种初始化就不能在主函数内改动了)
    }
    
    

    MyProject.cpp”:

    #include <iostream>
    #include <vector>
    
    #include "Time.h"
    
    using namespace std;   
    
    int main()
    {
    	Time mytime(1,2);       		      //只能赋两个参数值
    
    	mytime.print();
    	
    	return 0;
    }
    
    

    3、初始化列表的用法:
    https://www.csdn.net/gather_2f/MtTaEg0sMzgzOTgtYmxvZwO0O0OO0O0O.html

    形如:
    在这里插入图片描述
    例:

    Time.h”:

    #ifndef __MYTIME__
    #define __MYTIME__
    #include<iostream>
    
    
    using namespace std;
    class Time {
    public:
    	int Hour;
    	int Minute;
    	int Second;
    
    	Time(int tmphour, int tmpmin, int tmpsec) :Hour(tmphour), Minute(tmpmin), Second(tmpsec){}
    	
    	void print()
    	{
    		cout << Hour << endl;  
    		cout << Minute << endl; 
    		cout << Second << endl; 
    	}
    };
    #endif
    

    "Time.cpp":

    
    #include<iostream>
    #include "Time.h"
    
    using namespace std;
    

    啥都不用写。

    MyProject.cpp”:

    #include <iostream>
    #include <vector>
    
    #include "Time.h"
    
    using namespace std;   
    
    int main()
    {
    	Time mytime(1,2,3);         				  //随便赋值
    
    	mytime.print();
    	
    	return 0;
    }
    

    3、拷贝构造函数

    也称为复制构造函数
    拷贝构造函数参数为类对象本身的引用,根据一个已存在的对象复制出一个新的对象,一般在函数中会将已存在对象的数据成员的值复制一份到新创建的对象中。

    Time.h”:

    #ifndef __MYTIME__
    #define __MYTIME__
    #include<iostream>
    
    using namespace std;
    class Time {
    public:
    	int Hour;
    	int Minute;
    	int Second;
    
    	Time(int tmphour, int tmpmin, int tmpsec) :Hour(tmphour), Minute(tmpmin), Second(tmpsec) {}
    
    	Time(Time& T);
    
    	void print()
    	{
    		cout << Hour << endl;  
    		cout << Minute << endl; 
    		cout << Second << endl; 
    	}
    };
    #endif
    

    "Time.cpp":

    #include<iostream>
    #include "Time.h"
    
    using namespace std;
    
    Time::Time(Time& T)
    {
    	Hour = T.Hour;
    	Minute = T.Minute;
    	Second = T.Second;
    }
    

    MyProject.cpp”:

    #include <iostream>
    #include <vector>
    
    #include "Time.h"
    
    using namespace std;   
    
    int main()
    {
    	Time mytime(1,2,3);								// 调用一般构造函数
    
    	Time mytime1(mytime);							// 调用复制构造函数
    
    	mytime.print();
    
    	mytime1.print();
    	
    	return 0;
    }
    

    注意:若没有显示定义拷贝构造函数,则系统会默认创建一个拷贝构造函数,当类中有指针成员时,由系统默认创建的拷贝构造函数会存在“浅拷贝”的风险,因此必须显示定义拷贝构造函数。

    ···浅拷贝指的是在对对象复制时,只对对象中的数据成员进行简单的赋值。 若存在动态成员,就是增加一个指针,指向原来已经存在的内存。这样就造成两个指针指向了堆里的同一个空间。当这两个对象生命周期结束时,析构函数会被调用两次,同一个空间被两次free,造成野指针。
    ···深拷贝就是对于对象中的动态成员,不是简单的赋值,而是重新分配空间。

    4、转换构造函数

    在C++中,类的构造函数可以省略不写,这时C++会为它自动创建一个隐式默认构造函数(implicit default constructor);也可以由用户定义带参数的构造函数,构造函数也是一个成员函数,他可以被重载;
    当一个构造函数只有一个参数,而且该参数又不是本类的const引用时,这种构造函数称为转换构造函数

    Time.h”:
    (省事儿直接内联函数了)
    在这里插入图片描述
    MyProject.cpp”:

    单参数构造函数中,引用的写法不同,可能就会涉及隐式转换的问题。

    • 以下都为隐式初始化:
    
    Time mytime = (12, 13, 14, 15); //15,1,1  明显的隐式转换
    			//这里是c语言的逗号表达式,整体的值为最后一个值
    Time mytime = 16 ;				//代码含糊不清,存在临时对象及隐式转换的问题/16,1,1
    
    Time mytime = { 16 } ;			//这种写法较正常,可以让系统明确调用带一个参数16的构造函数/16,1,1
    
    

    如果,在“MyProject.cpp”中加一个 形参类型为Time 的普通函数fun();

    void fun(Time myt)    //这里如果写为void fun(Time& myt)就不能编译了 
    {
    	return;
    }
    
     // 这里如果写为void fun(Time& myt)就不能编译了 
    

    在这里插入图片描述

    则用一个数字就能调用:

    	fun(16); 					//系统对16到对象myt做了一个隐式转换,产生了一个临时对象myt
    
    所以出现了一个新的东西:explicit(显式):

    如果构造函数声明中带有explicit,则这个构造函数只能用于初始化显式类型转换

    Time.h”:

    explicit Time(int tmphour)
    

    不能编译://隐式转换

    Time mytime = (12, 13, 14, 15); 
    Time mytime = { 16 } ;		
    Time mytime = 16 ;			
    fun(16);
    

    可以编译://显式转换

    Time mytime ( 16 );				//少一个等号就可以
    Time mytime { 16 } ;		
    Time mytime = Time(16); 		//或者Time{16}
    fun(Time(16)); 					//生成临时对象
    

    如果explicit用于无参的构造函数:

    	explicit Time();
    

    则:

    	Time mytime {};				//可以,显式转换
    	Time mytime = {};			//不可以,多一个等号就是隐式初始化了(构造并初始化)
    	fun({});					//不可以,隐式转换
    	fun({1,2,3});				//不可以,隐式转换
    	fun(Time{});				//显式转换,调用无参构造函数生成临时对象
    	fun(Time{1,2,3});			//显式转换,调用三个参数的构造函数生成临时对象
    

    总结:建议单参数构造函数都声明为explicit,防止出现未知错误

    三、构造函数的一些问题

    1、

    不同于其他成员函数,构造函数不能被声明为const
    当我们创建类的一个const对象时,直到构造函数完成初始化过程,对象才能真正取得其“常量”属性。因此,构造函数在const对象的构造过程中可以向其写值。

    2、

    函数定义写在类的外部和写在类的内部有什么区别?

    调用方式不同。

    • 在类里面定义的是内联函数(涉及到内联函数inline):

    调用的时候不发生控制权转移,作为函数体本身一个模块进行调用。

    • 在类外面定义的函数:

    情况相反,调用的时候需要开辟一部分空间。

    总结就是类里面定义的调用更快,更节省内存

    3、

    在C++11新标准中,如果我们需要默认的行为,那么可以通过在参数列表后写上“=default”(不含引号)来要求编译器生成构造函数。
    其中,“=default”即可以和声明一起出现在类的内部,也可以作为定义出现在类的外部。
    在这里插入图片描述

    =default的详细用法:https://blog.csdn.net/weixin_38339025/article/details/89161324

    4、

    通常情况下,我们将构造函数声明为public的,可以供外部调用。然而有时候我们会将构造函数声明为private或protected的:
    (1)如果类的作者不希望用户直接构造一个类对象,着只是希望用户构造这个类的子类,那么就可以将构造函数声明为protected,而将该类的子类声明为public。
    (2)如果将构造函数声明为private,那只有这个类的成员函数才能构造这个类的对象。

    5、

    所有的构造函数都可以用初始化列表表示。

    感谢以下文章:

    https://blog.csdn.net/qq_40246263/article/details/78334675?utm_medium=distribute.pc_relevant.none-task-blog-title-7&spm=1001.2101.3001.4242

    https://blog.csdn.net/china_jeffery/article/details/79288103?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

    https://blog.csdn.net/qq_37568748/article/details/82014064

    https://blog.csdn.net/hongzhiyong118/article/details/87967935?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param

    https://zhuanlan.zhihu.com/p/168787937

    https://blog.csdn.net/lixiaogang_theanswer/article/details/81090622

    展开全文
  • 一、拷贝构造函数 功能:使用一个已经存在的对象来初始化一个新的同一类型的对象 ...下面一个String的例子,说明拷贝构造函数的使用: #ifndef _STRING_H_ #define _STRING_H_ class String { p
  • 问题:对c++初学者来说存在一个误区,如果类没有定义任何构造函数,编译器会自动生成默认的构造函数。...以下情况编译器会自动合成默认构造函数 情况1&nbsp;含有类对象...
  • 1. 深拷贝和浅拷贝(拷贝构造函数的使用)   时候需要自己定义拷贝构造函数,以避免浅拷贝...在什么情况下系统会调用拷贝构造函数:(三情况) (1)用类的一个对象去初始化另一个对象时 (2)当函数的形参
  • 时候我们需要不同对象可能需要不同的初值,如此场景下,了带参数的构造函数。1. 带参数的构造函数构造函数的一般格式为:构造函数名(类型1 形参1,类型2 形参2,···)定义对象的一般格式:类名 对象名(实参...
  • 第一是类成员中成员是类对象,并且该成员的类含有默认构造函数,那么C++编译器会帮你给这个类也生成一个默认构造函数,用来调用其成员对象的构造函数,完成该成员的初始化构造。需要强调的是,如果这个成员的类...
  • C++ 中的几种构造函数

    2020-11-01 17:16:13
    我们对一个对象的操作一般分为下面四 创建 拷贝 ...因为第一种构造函数只含有一个实参,因为它定义了转换为此类型的隐式转换机制,这种构造函数叫做转换构造函数: A a = 1; 我们可以使用explici
  • C++类的几种构造函数

    2019-09-02 17:51:54
    假定类名 CAnyTest 不罗嗦,直接看以下代码 ...普通参数构造函数 CAnyTest(int nValue); CAnyTest(int nValue = 0);// 不能于无参构造同时使用,二义性 拷贝构造函数 CAnyTest(CAnyTest&); CAnyTes...
  • C++中的几种构造函数

    千次阅读 2018-09-25 09:56:35
    C++中的构造函数 C++中的构造函数可以分为4类: (1)默认构造函数。以Student类为例,默认构造函数的原型为 Student();//没有参数 (2)初始化构造函数 Student(int num,int age);//参数 (3)复制...
  • 1. 深拷贝和浅拷贝(拷贝构造函数的使用) ...在什么情况下系统会调用拷贝构造函数:(三情况) (1)用类的一个对象去初始化另一个对象时 (2)当函数的形参是类的对象时(也就是值传递时),如果...
  • //无参构造 注意:调用无参构造时不要加括号,不然程序运行默认是函数 类名 p2(10);//构造 2.显示法 类名 p1;//无参构造 类名 p2=person(10);//构造 person(10);//匿名对象,执行完就被回收 3.隐式转换...
  • 1.1当父类中同时有无参和构造函数时,子类继承父类,调用子类的无参构造函数,这是无论写不写super();其结果都一样,都是先调用父类的无参构造,再调用子类的无参构造,代码如下 class Father{ String s...
  • 构造函数的特点: 构造函数的首字母必须大写,用来区分于普通函数 内部使用this对象,来指向即将要生成的实例对象 使用new来生成实例对象 构造函数的作用: 当你需要大批量的写对象的时候,就需要用到构造函数,它...
  • JS几种方法构造函数

    千次阅读 2016-08-08 10:14:50
    函数声明表达式hoisted(); // logs "foo"function hoisted() { console.log("foo"); }function操作符var math = { 'factorial': function factorial(n) { if (n ) return 1; return n * factorial(n - 1)
  • 浅谈C++中的几种构造函数

    千次阅读 2018-02-28 13:12:52
    C++中的构造函数C++中的构造函数可以分为4类: (1)默认构造...//参数 (3)复制(拷贝)构造函数 Student(Student&amp;);//形参是本类对象的引用 (4)转换构造函数 Student(int r) ;//形参时其他...
  • 创建对象有几种方法 1、 var o1 = {name:'o1'} var o11 = new Object({name:'o11'}) 2、显式构造函数 var M = function(){ this.name = 'M' } var o2 = new M()//凡是通过new的函数都是构造函数 3、 var P = {name:...
  • 今天看到书上对对象直接用=赋值调用构造函数,十分不解,浴室百度了一下发现四种方式可以对构造函数传参,觉得这几种方式只是是写C++语言的人规定的四种形式,都可以编译使用。 // classes and uniform ...
  • 类的构造函数是类的一特殊的成员函数,它会在每次创建类的新对象时执行。 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型void,也不会返回 void。构造函数可用于为某些成员变量设置初始值。 01 ...
  • C++构造函数与传默认值的关系

    千次阅读 2015-07-27 16:28:46
    类的构造函数有几种形式: 1 不为类提供任何构造函数,系统将为类提供一个空的默认构造函数,不对对象成员值做任何改变。在set函数对其赋值,由get函数进行取值。 2 自己手动为类添加空参数类型的默认构造函数,...
  • 构造函数

    2018-03-21 21:45:29
     构造函数的特性以下点: (1)构造函数名和类名完全相同; (2)没有返回值(void也算返回值); (3)构造函数创建对象的时候调用构造函数; (4)默认的构造函数没有参数(如果自己写了构造函数,默认的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,842
精华内容 1,136
关键字:

构造函数有几种