精华内容
下载资源
问答
  • 其作用以下几点:1、根据另一个同类型的对象显示或隐式初始化一个对象2、复制一个对象,将它作为实参传递给一个函数3、从函数返回时复制一个对象4、初始化顺序容器的元素5、根据元素初始化列表初...

    写在前面

    上次的笔记中简要的探索了一下C++中类的构造函数的一些特性,这篇笔记将做进一步的探索。主要是复制构造函数的使用。

    复制构造函数

    复制构造函数也称拷贝构造函数,它只有单个形参,且该形参是对本类类型对象的引用。其作用有以下几点:
    1、根据另一个同类型的对象显示或隐式初始化一个对象
    2、复制一个对象,将它作为实参传递给一个函数
    3、从函数返回时复制一个对象
    4、初始化顺序容器中的元素
    5、根据元素初始化列表初始化数组元素

    编译器合成的复制构造函数

    如同默认构造函数一样,如果我们没有显示地定义复制构造函数,编译器将为我们合成一个复制构造函数。合成复制构造函数将新对象初始化为原对象的副本。编译器对每个数据成员进行注意初始化。合成复制构造函数直接复制内置类型成员的值,对于类类型的成员,则使用该类的复制构造函数进行复制。如果某个类包含数组类型的成员,那么合成复制构造函数将复制数组的每个元素。
    测试代码如下:

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    class myClass{
    public:
        myClass(int i1, char c1)//普通构造函数
        {
            a = i1;
            c = c1;
        }
    
        int a;
        char c;
    };
    
    int main()
    {
        myClass class1(1, 'a');
        myClass class2( class1);//调用合成的复制构造函数
    
        cout<<"class1 is: "<<class1.a<<" "<<class1.c<<endl;
        cout<<"class2 is: "<<class2.a<<" "<<class2.c<<endl;
    
        system("pause");
        return 0;
    }
    

    运行结果如下:
    enter description here
    class1中的成员都被复制到了class2中。合成复制构造函数使用的是浅拷贝的策略。也就是说,如果class1中有指针类型的成员,那么使用合成的复制构造函数时,class2中对应的那个指针与class1中的指针指向的是同一片地址。

    自定义的复制构造函数

    自己定义复制构造函数时,可将复制构造函数的参数设置为类类型的引用,通常用const修饰参数。尽管也可以接受非const引用的复制构造函数。
    测试代码如下:

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    class myClass{
    public:
        myClass(int i1, char c1)//普通构造函数
        {
            a = i1;
            c = c1;
        }
    
        myClass( const myClass& myclass)//复制构造函数
        {
    
        }
    
    
        int a;
        char c;
    };
    
    int main()
    {
        myClass class1(1, 'a');
        myClass class2( class1);//调用自定义的复制构造函数
    
        cout<<"class1 is: "<<class1.a<<" "<<class1.c<<endl;
        cout<<"class2 is: "<<class2.a<<" "<<class2.c<<endl;
    
        system("pause");
        return 0;
    }
    

    上述代码自定义了拷贝构造函数,尽管自定义的复制构造函数函数体为空,但这时系统不再合成复制构造函数,而是调用用户自定义的,此时的运行结果如下:
    enter description here
    由于自定义复制构造函数函数体为空,因此没有完成复制。
    修改复制构造函如下:

        myClass( const myClass& myclass)
        {
            this->a = myclass.a;
            this->c = myclass.c;
        }
    

    我们可以让自定义的复制构造函数在复制时采用深拷贝的方式。此外,当没有对当前的类重载运行符”=“时,下面这句话也是调用复制构造函数:

        myClass class3 = class1;
    

    总结

    这篇笔记写得有点匆忙,之后有时间需要进一步完善。

    展开全文
  • C++构造函数 C++构造函数可以分为4: (1)默认构造函数。...//形参时其他类型变量,且只有一个形参 默认和初始化构造函数 默认构造函数和初始化构造函数在定义的对象的时候,完成对象

    C++中的构造函数

    C++中的构造函数可以分为4类:
    (1)默认构造函数。以Student类为例,默认构造函数的原型为
    Student();//没有参数
    (2)初始化构造函数
    Student(int num,int age);//有参数
    (3)复制(拷贝)构造函数
    Student(Student&);//形参是本类对象的引用
    (4)转换构造函数
    Student(int r) ;//形参时其他类型变量,且只有一个形参

    默认和初始化构造函数

    默认构造函数和初始化构造函数在定义类的对象的时候,完成对象的初始化工作。

    class Student
    {
    public:
    	//默认构造函数
    	Student()
    	{
    	   num=1001;
           age=18;	   
    	}
    	//初始化构造函数
    	Student(int n,int a):num(n),age(a){}
    private:
    	int num;
    	int age;
    };
    int main()
    {
    	//用默认构造函数初始化对象S1
    	Student s1;
    	//用初始化构造函数初始化对象S2
    	Student s2(1002,18);
    	return 0;
    }
    

    复制(拷贝)构造函数##

    • 复制构造函数用于复制本类的对象
     Student  s2(1002,1008);
     Student  s3(s2);//将对象s2复制给s3。注意复制和赋值的概念不同。
    
    • 1
    • 2
    • 下面这种情况叫做赋值,不调用复制构造函数。
     Student s4;
     s4=s2;//这种情况叫做赋值,自己体会吧
    
    • 1
    • 2
    • 大多数时候,在类中我们没有声明复制构造函数,而是C++自动为我们生成了一个复制构造函数,如下:
     Student(Student &b)
    	{
    		this.x=b.x;
    		this.y=b.y;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 如代码所示,它的作用是将一个已存在的对象b,复制给调用该复制构造函数的对象。
    • 具体来说,在一下情况发生时,会调用复制构造函数:
    1. 用复制的方法,建立一个新对象。
    2. 函数的形参为类的对象时。(这点和普通类型的形参类似,要复制一份实参给函数)
    3. 函数的返回值是类的对象,在函数中定义的对象,在函数结束后消息,需要调用复制构造函数,建立一个临时的对象,将该临时对象返回给调用该函数的对象。
    4. 默认的复制构造函数,在某些情况下会出现问题,想深入学习可以自行百度。

    转换构造函数

    • 转换构造函数用于将其他类型的变量,隐式转换为本类对象。
    • 下面的转换构造函数,将int类型的r转换为Student类型的对象,对象的age为r,num为1004.
     Student(int r)int num=1004int age= r;
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 转换构造函数可以用在哪里?
    • 假如重载了+号运算符,使得两个Student类的对象可以相加,其结果为两个对象的成员变量age之和。
    Student s1(01,18);
    Student s2(02,20);
    s1+s2;  //其值就是s1.age + s2.age = 18+20=36。
    
    • 1
    • 2
    • 3
    • **那么 s1+19 呢(类对象与int直接相加)? **
    • 因为我们定义了 转换构造函数,那么 s1+19,执行如果过程:
    1. 首选调用+号运算符,发现19不是Student类的对象,而是int类型
    2. 然后调用转换构造函数,将19变为Student(19)
    3. 现在便可以进行加法运算,其值是s1.age+ (TempStudentObject).age=18+19 = 37
    • 这里只是很浅的讲了这几类构造函数的基本概念,如果希望深入学习,网上有很多参考资料.
    展开全文
  • 当你本地创建一个webservice实例的时候,创建的其实是本地的代理的实例,这个时候并没有跟服务器端进行通信,无法将参数传送到服务器端,并且只有真正调用web service方法的时候,才与服务器端进行了通信...

           确切的是说重载了带参构造函数也无效,不会起作用。且如果重载了带参构造函数,必要要有个无参构造函数。

           在.net当中webservice客户端只是在本地生成了一个代理类,这个代理类封装并维护与服务器端的通信。当你在本地创建一个webservice类实例的时候,创建的其实是本地的代理类的实例,这个时候并没有跟服务器端进行通信,无法将参数传送到服务器端,并且只有你在真正调用web service方法的时候,才与服务器端进行了通信。

           所以当你webservice类中定义了带参构造函数,准备在客户端进行参数传递的想法是行不通的,webservice客户端只能调用无参构造函数。
    测试验证结果:
    编写一个客户端和服务器端,将断点设置在客户端创建服务实例的地方,启用fildder,跟踪http,你可以发现,当执行完创建webservice实例的时候,fildder没有跟踪到通信,当代码运行到调用服务器端方法的时候,可以发现已经发送了一个soap请求过去了,并有xml的响应回来。结论:在.net中,当在本地创建web service实例的时候是没有与服务器端进行通信的,也就没有办法传递参数给服务器端,只有当真正调用webservice方法的时候才与服务器端进行通信,所以webservice是无法使用带参数的构造函数的。
    不过有个变通的方法,那就是用一个web方法执行你想传递参数的代码就可以,也就是一个假的带参数构造函数。

    展开全文
  • 定义默认构造函数 默认构造函数就是没有显示提供初始化时调用的构造函数,它...任何一个类有且只有一个默认构造函数。如果定义的类中没有显式定义任何构造函数,编译器会自动为该类生成默认构造函数,称为合成默认构

    定义默认构造函数

    默认构造函数就是在没有显示提供初始化时调用的构造函数,它是一个不带参数的构造函数。如果定义某个类的对象时没有提供初始化式就会使用默认构造函数

    定义默认构造函数(default constructor)的一般形式为:

    类名() {
    	函数体
    }
    

    它由不带参数的构造函数,或者所有形参均是默认参数的构造函数定义。与默认构造函数相对应的对象定义形式为:

    类名 对象名;
    

    任何一个类有且只有一个默认构造函数。如果定义的类中没有显式定义任何构造函数,编译器会自动为该类生成默认构造函数,称为合成默认构造函数(synthesized default constructor)

    一个类哪怕只定义了一个构造函数,编译器也不会再生成默认构造函数。换言之,如果为类定义了一个带参数的构造函数,还想要无参数的构造函数,就必须自己定义它

    一般地,任何一个类都应定义一个默认构造函数。因为,在很多情况下,默认构造函数是由编译器隐式调用的

    隐式类类型转换

    为了实现其他类型到类类型的隐式转换,需要定义合适的构造函数。可以用单个实参调用的构造函数(称为转换构造函数)定义从形参类型到该类型的隐式转换

    隐式类类型转换举例

    #include<iostream>
    using namespace std;
    
    class Data { //Data类定义
    	public:
    		Data(const string& str="") : s1(str) { }
    		void SetString(const Data& r) {
    			s1 =  r.s1; }
    		void print() { cout<<s1<<endl; }
    	private:
    		string s1;
    };
    
    int main()
    {
    	Data a,b,c("world");
    	string i="string";
    	a.SetString(c);
    	b.SetString(string("world")); //隐式转换
    	a.print(); b.print();
    	Data d=Data(i); //隐式转换
    	d.print();
    	return 0;
    }
    

    使用单个参数的构造函数来进行类类型转换的方法可以总结如下:
    (1)先声明一个类;
    (2)在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的数据类型,即转换构造函数的一般形式为:

    类名(const 指定数据类型&obj)
    

    (3)采用转换构造函数定义对象时即进行类型转换,一般形式为:

    类名(指定数据类型的数据对象)
    

    可以禁止由构造函数定义的隐式转换,方法是通过将构造函数声明为explicit,来防止在需要隐式转换的上下文中使用构造函数

    C++关键字explicit用来修饰类的构造函数,指明该构造函数是显式的。explicit关键字只能用于类内部的构造函数声明上,在类定义外部不能重复它

    一般地,除非有明显的理由想要定义隐式转换,否则,单形参构造函数应该为explicit。将构造函数设置为explicit可以避免错误,如果真需要转换,可以显式地构造对象

    展开全文
  • 构造函数和析构函数

    2020-11-01 17:07:57
    构造函数与析构函数 由于c++中类数据成员多数为私有的,要对他们进行初始化,必须...5.构造函数可以在类中定义,也可以类外定义。 6.如果类说明中没有给出构造函数,c++编译器自动给出一个缺省的构造函数。(有且只有
  • 构造函数

    2017-04-18 19:20:25
    合成的默认构造函数:编译器创建的构造函数 ...例如,如果类中包含一个其他类型的成员,该成员的类型没有默认构造函数,此时,编译器无法初始化该成员。 一、内置类型 如int, char, float, unsigned等。内置类型是最
  •  一个特殊的成员函数,函数名与类名相同,创建类型对象时,由编译器自动调用,对象的生命周期只调用一次,以保证每个数据成员都有一个合适的初始值。初始化阶段与普通计算阶段。(2)拷贝构造函数 ...
  • 约束:抽象方法有且只有一个,即不能有多个抽象方法,接口中覆写Object类中的public方法(如equals),不算是函数式接口的方法。被@FunctionalInterface注解该接口,没有该注解的接口满足约束也行。Java8中,满足...
  • 拷贝构造函数

    2012-09-26 10:47:35
    拷贝构造函数只有一个形参,形参为本类类对象的应用的构造函数。 拷贝构造函数在下列情况下使用: 1、更具同类类型来初始化一...如果一个类中有指针成员或者复制对象是某些特殊要求,如要求每个对象一个唯
  •  不能重复定义,每个类有且只有一个;  如果不写相当于默认一个无语句无参数的空函数。  构造函数除了具有一般成员函数的特征外,还具有一些特殊的性质:  (1)构造函数的名字必须与类名相同  (2)构造...
  • C++剖析— 转换构造函数 参考自 狄泰 C++深度解析 我们知道标准的数据类型之间是有隐式转换的,转换...有且只有一个参数 参数是基本数据类型 参数不是自身的类型 我们知道,也是一个数据类型,那么问题来了...
  • 如果用户自己没有是声明构造函数,编译器就会自己生成一个默认构造函数,该默认构造函数在以下几种情况是nontrivial的,只有在以下四种情况下,编译器才会合成默认构造函数内置数据类型都不会被初始化,只有base...
  • 该类没有任何构造函数,但其包含一个类类型的成员变量,而该成员变量所属的类一个默认构造函数. 如下代码, B类没有任何构造函数,但其包含A类类型的成员变量a,A类一个默认构造函数,这时编译器会为B类自动合成...
  • 约束:抽象方法有且只有一个,即不能有多个抽象方法,接口中覆写Object类中的public方法(如equal),不算是函数式接口的方法。 被@FunctionalInterface注解该接口,没有该注解的接口满足约束也行。 自定义一...
  • 约束:抽象方法有且只有一个,即不能有多个抽象方法,接口中覆写Object类中的public方法(如equals),不算是函数式接口的方法。被@FunctionalInterface注解该接口,没有该注解的接口满足约束也行。Java8中,满足...
  • JAVA基础:构造

    2011-06-29 21:43:01
    5、只有在类中没有其他构造器时,虚拟机才提供默认的构造器 二、类的初始化过程 1、为对象分配内存。 2、内存清零,所有字段都被初始化为默认值 3、调用构造函数父类的构造函数先被调用 4、...
  • 单例模式单例模式(Singleton)是一种常用的设计模式,它是创建型模式的一种,适用于一个类有且只有一个实例的情况,也就是说,单例模式确保了某个类只有一个实例(对象)存在。单例模式定义的三个要素定义私有的静态...
  • C++随笔-转换函数

    2019-05-04 09:58:21
    默认使用对象的构造...当构造函数有多个参数时,只有一个参数没有默认值,而其他参数都配置了默认值,则同样可以被自动隐式地作为转换函数。同时,如果担心隐式转换会带来意想不到的错误,可以使用关键字explicit...
  • 通过我们已经学过的知识,你可以编写一个最简单的程序输出一个也许是程序世界最有名的词语: echo "Hello World!"; ?> First PHP page // Single line C++ style comment /* printing the message */ ...
  • 如果要生成一个对象实例,需要先定义一个构造函数,然后通过new操作符来完成。构造函数示例: //函数名和实例化构造名相同大写(非强制,但这么写助于区分构造函数和普通函数) function Person(name,age) { ...
  • 它的作用是确保一个类在整个工程中有且只有一个实例。可以多个不同的类中很方便的所需要的类的方法。 应用领域:常用游戏编程和多线程编程中,读取配置文件,写入日志。 原理: 它的构造函数是私有的,你不能去...
  • 【C++】析构函数详解

    2021-01-29 10:13:43
    一个类有且只有一个析构函数。若用户没有显式定义,系统会自动生成默认的析构函数。(不一定会,下面进行解答) 1、下面这个类中,并没有显示定义析构函数,但是编辑器不会生成默认的析构函数,因为个类中...
  • 它的作用是确保一个类在整个工程中有且只有一个实例。可以多个不同的类中很方便的所需要的类的方法。 原理: 它的构造函数是私有的,你不能去new它。该单例类里面已经实例化好了一个了,并且是static的,并提供...
  • JVM将为的instance和static变量赋上缺省值(默认值),包括数组array的每一个元素--而不用再写初始化赋值语句。切记:局部变量是没有缺省值的,必须手动初始化!这一缺省赋值过程是对象的构造函数调用之前完成...
  • 单件模式就是说整个程序,这个类的对象有且只有一个。比如对于个人电脑,键盘就可以认为有且只有一个。 将构造函数声明为私有,就不能随意的创建对象了,这样才能保证对象有且只有一个。 **********************...
  • 程序提供默认析构函数类成员中new分配的动态存储空间时,析构函数将使用delete来释放内存,如果类中只有自动变量,那么析构函数将什么都不用做。 声明的对象将其作用域结束后自动调用析构函数,若是用new...
  • 对象所占用的内存空间打大小是所有数据成员(函数单独存放且一个类只有一份) 构造函数在对象创建时会自动调用。 一旦为类定义了带参数的构造函数,编译器将不再为类提供默认构造函数。(解决方法是要么重载一...
  • Java可以在一个类中使用 多次构造函数,以实现不同的功能。 3、python中的类变量可以直接用类名调用,多个类实例,其类变量也多个,并 不是如同java中一样,类变量是单独的一个变量内存中只有一个类变量。...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 239
精华内容 95
关键字:

在一个类中构造函数有且只有一个