精华内容
下载资源
问答
  • 复制构造函数只有一个参数,由于在创建时传入的同种类型的对象,所以一个很自然的想法将该类型的对象作为参数,像这样: Sample (Sample a); 不幸的,即使这样朴实无华的声明也隐含了一个微妙的错误,呵,我们来...
    复制构造函数只有一个参数,由于在创建时传入的是同种类型的对象,所以一个很自然的想法是将该类型的对象作为参数,像这样:
         Sample (Sample a);
         不幸的是,即使是这样朴实无华的声明也隐含了一个微妙的错误,呵,我们来看看:当某个时候需要以一个Sample对象的值来为一个新对象进行初始化时,编译器会在各个重载的构造函数版本(如果有多个的话)搜寻,它找到的这个版本,发现声明参数与传入的对象一致,因此该构造函数将会被调用。目前为止,一切都在我们的意料之中,但问题很快来了:该函数的参数我们使用了值传递的方式,按照前面的分析,这需要调用复制构造函数,于是编译器又再度搜寻,最后当然又找到了它,于是进行调用,但同样地,传参时又要进行复制,于是再调用...这个过程周而复始,每次都是到了函数入口处就进行递归,直到堆栈空间耗尽,程序崩溃...
    
    由是观之,值传递看来是行不通的了;我想C语言的用户这时很快会反应到与值传递对应的方式:地址传递(传址),于是声明变为这样:
         Sample Sample *p);
         只作为一般的构造函数,它应该可以运行得很好,但别忘了我们要提供的是复制构造函数,它要求能够接受一个同类型对象,像这样:
         Sample a;
         Sample b(a);
         而不是接受指针:
         Sample a;
         Sample b(&a);   // 还要取地址?当然,它可以正确运行,但...
         虽然在初始化对象时可以像上面一样人为加一个取址符,但在函数参数表中(或者函数返回)进行值传递时,编译器可不知道在找不着合适定义的情况下牵就选择你的指针版本。
    
    只有单个形参,而且该形参是对本类类型对象的引用(常用 const 修饰),这样的构造函数称为复制
    
    构造函数
    
    复制构造函数可用于:
    1. 根据另一个同类型的对象显式或隐式初始化一个对象
    2. 复制一个对象,将它作为实参传给一个函数
    3. 从函数返回时复制一个对象
    4. 初始化顺序容器中的元素
    5. 根据元素初始化式列表初始化数组元素
    
    当用于类类型对象时,初始化的复制形式和直接形式有所不同:直接初始化直接调用与实参匹配的构
    
    造函数,复制初始化总是调用复制构造函数
    
    对于类类型对象,只有指定单个实参或显式创建一个临时对象用于复制时,才使用复制初始化
    
    当形参或返回值为类类型时,由复制构造函数进行复制
    
    如果没有为类类型数组提供元素初始化式,则将用默认构造函数初始化每个元素
    
    如果我们没有定义复制构造函数,编译器就会为我们合成一个
    
    与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数
    
    合成复制构造函数的行为是,执行逐个成员初始化,将新对象初始化为原对象的副本
    
    虽然一般不能复制数组,但如果一个类具有数组成员,则合成复制构造函数将复制数组,复制数组时
    
    合成复制构造函数将复制数组的每一个元素
    
    
    逐个成员初始化最简单的概念模型是,将合成复制构造函数看作这样一个构造函数:其中每个数据成
    
    员在构造函数初始化列表中进行初始化
    
    虽然也可以定义接受非 const 引用的复制构造函数,但形参通常是一个 const 引用
    
    因为用于向函数传递对象和从函数返回对象,该构造函数一般不应设置为 explicit
    
    有些类必须对复制对象时发生的事情加以控制,这样的类经常有一个数据成员是指针,或者有成员表
    
    示在构造函数中分配的其他资源,而另一些类在创建新对象时必须做一些特定工作,这两种情况下,
    
    都必须定义复制构造函数
    
    为了防止复制,类必须显式声明其复制构造函数为 private
    
    类的友元和成员仍可以进行复制,如果想要连友元和成员中的复制也禁止,就可以声明一个
    
    (private)复制构造函数但不对其定义
    
    一般来说,最好显式或隐式定义默认构造函数和复制构造函数,只有不存在其他构造函数时才合成默
    
    认构造函数。如果定义了复制构造函数,也必须定义默认构造函数
    
    Cpp代码 
    #include <iostream>   
    #include <string>   
    #include <fstream>   
    #include <vector>   
    using namespace std;   
      
    struct NoName {   
            NoName(): pstring(new string), i(0), d(0) { }   
            NoName(const NoName& noName): i(noName.i), d(noName.d)   
            {   
                    *pstring = *(noName.pstring);                 
            }   
    private:   
             string *pstring;   
            int     i;   
            double d;   
    };   
      
    class Foo {   
         public:   
             Foo();           // default constructor   
             Foo(const Foo&); // copy constructor   
            // ...   
    };   
      
    int main()   
    {   
         string null_book = "9-999-99999-9"; // copy-initialization   
         string dots(10, '.');               // direct-initialization   
           
         string empty_copy = string();       // copy-initialization   
         string empty_direct;                // direct-initialization   
      
         ifstream file1("filename"); // ok: direct initialization   
        //ifstream file2 = "filename";   error: copy constructor is private   
           
        // default string constructor and five string copy constructors invoked   
         vector<string> svec(5);   
      
        return 0;   
    }  
    展开全文
  • 复制构造函数只有一个参数,由于在创建时传入的同种类型的对象,所以一个很自然的想法将该类型的对象作为参数,像这样:  Sample (Sample a);  不幸的,即使这样朴实无华的声明也隐含了一个微妙的错误,呵,...
    复制构造函数只有一个参数,由于在创建时传入的是同种类型的对象,所以一个很自然的想法是将该类型的对象作为参数,像这样:
         Sample (Sample a);
         不幸的是,即使是这样朴实无华的声明也隐含了一个微妙的错误,呵,我们来看看:当某个时候需要以一个Sample对象的值来为一个新对象进行初始化时,编译器会在各个重载的构造函数版本(如果有多个的话)搜寻,它找到的这个版本,发现声明参数与传入的对象一致,因此该构造函数将会被调用。目前为止,一切都在我们的意料之中,但问题很快来了:该函数的参数我们使用了值传递的方式,按照前面的分析,这需要调用复制构造函数,于是编译器又再度搜寻,最后当然又找到了它,于是进行调用,但同样地,传参时又要进行复制,于是再调用...这个过程周而复始,每次都是到了函数入口处就进行递归,直到堆栈空间耗尽,程序崩溃...

    由是观之,值传递看来是行不通的了;我想C语言的用户这时很快会反应到与值传递对应的方式:地址传递(传址),于是声明变为这样:
         Sample Sample *p);
         只作为一般的构造函数,它应该可以运行得很好,但别忘了我们要提供的是复制构造函数,它要求能够接受一个同类型对象,像这样:
         Sample a;
         Sample b(a);
         而不是接受指针:
         Sample a;
         Sample b(&a);   // 还要取地址?当然,它可以正确运行,但...
         虽然在初始化对象时可以像上面一样人为加一个取址符,但在函数参数表中(或者函数返回)进行值传递时,编译器可不知道在找不着合适定义的情况下牵就选择你的指针版本。

    只有单个形参,而且该形参是对本类类型对象的引用(常用 const 修饰),这样的构造函数称为复制

    构造函数

    复制构造函数可用于:
    1. 根据另一个同类型的对象显式或隐式初始化一个对象
    2. 复制一个对象,将它作为实参传给一个函数
    3. 从函数返回时复制一个对象
    4. 初始化顺序容器中的元素
    5. 根据元素初始化式列表初始化数组元素

    当用于类类型对象时,初始化的复制形式和直接形式有所不同:直接初始化直接调用与实参匹配的构

    造函数,复制初始化总是调用复制构造函数

    对于类类型对象,只有指定单个实参或显式创建一个临时对象用于复制时,才使用复制初始化

    当形参或返回值为类类型时,由复制构造函数进行复制

    如果没有为类类型数组提供元素初始化式,则将用默认构造函数初始化每个元素

    如果我们没有定义复制构造函数,编译器就会为我们合成一个

    与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数

    合成复制构造函数的行为是,执行逐个成员初始化,将新对象初始化为原对象的副本

    虽然一般不能复制数组,但如果一个类具有数组成员,则合成复制构造函数将复制数组,复制数组时

    合成复制构造函数将复制数组的每一个元素


    逐个成员初始化最简单的概念模型是,将合成复制构造函数看作这样一个构造函数:其中每个数据成

    员在构造函数初始化列表中进行初始化

    虽然也可以定义接受非 const 引用的复制构造函数,但形参通常是一个 const 引用

    因为用于向函数传递对象和从函数返回对象,该构造函数一般不应设置为 explicit

    有些类必须对复制对象时发生的事情加以控制,这样的类经常有一个数据成员是指针,或者有成员表

    示在构造函数中分配的其他资源,而另一些类在创建新对象时必须做一些特定工作,这两种情况下,

    都必须定义复制构造函数

    为了防止复制,类必须显式声明其复制构造函数为 private

    类的友元和成员仍可以进行复制,如果想要连友元和成员中的复制也禁止,就可以声明一个

    (private)复制构造函数但不对其定义

    一般来说,最好显式或隐式定义默认构造函数和复制构造函数,只有不存在其他构造函数时才合成默

    认构造函数。如果定义了复制构造函数,也必须定义默认构造函数

    Cpp代码 
    #include <iostream>   
    #include <string>   
    #include <fstream>   
    #include <vector>   
    using namespace std;   
      
    struct NoName {   
            NoName(): pstring(new string), i(0), d(0) { }   
            NoName(const NoName& noName): i(noName.i), d(noName.d)   
            {   
                    *pstring = *(noName.pstring);                 
            }   
    private:   
             string *pstring;   
            int     i;   
            double d;   
    };   
      
    class Foo {   
         public:   
             Foo();           // default constructor   
             Foo(const Foo&); // copy constructor   
            // ...   
    };   
      
    int main()   
    {   
         string null_book = "9-999-99999-9"; // copy-initialization   
         string dots(10, '.');               // direct-initialization   
           
         string empty_copy = string();       // copy-initialization   
         string empty_direct;                // direct-initialization   
      
         ifstream file1("filename"); // ok: direct initialization   
        //ifstream file2 = "filename";   error: copy constructor is private   
           
        // default string constructor and five string copy constructors invoked   
         vector<string> svec(5);   
      
        return 0;   
    }  
    展开全文
  • 什么是形参什么是实参?

    千次阅读 2020-05-13 21:27:42
    什么是形参什么是实参? 什么是形参形参全称叫做“形式参数”,也一个虚拟的参数,在定义方法的时候使用的参数,形参是方法被调用时用于接收实参值的变量。 什么是实参? 实参全称叫做“实际参数”,顾名思义...

    什么是形参?什么是实参?

    什么是形参?
    形参全称叫做“形式参数”,也是一个虚拟的参数,在定义方法的时候使用的参数,形参是方法被调用时用于接收实参值的变量。
    什么是实参?
    实参全称叫做“实际参数”,顾名思义就是实际存在的参数,实参可以是常量、变量、表达式、类等,实参必须要有确定的值。
    总结:形参与实参的类型、个数是要一一对应的

    我们看下下面这段代码,来更加深入的了解什么是形参?什么是实参?

    public class MethodTest2 {
    	public static void main(String[] args) {	
    		sum(4,6);//这里边的4,6就是实参
    	}
    	public static void sum(int a,int b){
    	//sum(int a,int b)   这里边的int a,int b 就是形参 
    	//它们的类型和传进来的4,6的类型和个数都是一一对应的
    	//这里边的a就是4 b就是6
    		int c = a + b;//相当于int c = 4 + 6;
    		System.out.println("a + b = " + c);
    		//结果:a+b=10
    	}
    }
    
    展开全文
  • class myclass//一个简单的类 {}; myclass a 这样通过myclass 的构造函数...参数a也必须调用myclass的构造函数来生成对象, 那么在一个类的拷贝构造函数中写出了这样形式 class myclass { myclass(myclass ...
    class myclass//一个简单的类
    {};

    myclass a
    这样通过myclass 的构造函数创建了一个myclass的对象,
    同样样在函数传参的时候

    void fun(myclass a)

    参数a也必须调用myclass的构造函数来生成对象,

    那么在一个类的拷贝构造函数中写出了这样形式

    class myclass
    {
        myclass(myclass mc);
    }

    拷贝构造函数里的参数 mc给它一个非引用,非指针的参数,它一定会调用该类型的构造函数。, 那就是调用自身,会发生死循环导致栈溢出.

    但是如果传递指针或者引用,那么就等于传递了一个明确的地址类型,就不会发生调用拷贝函数的问题

    展开全文
  • 复制构造函数只有一个参数,由于在创建时传入的同种类型的对象,所以一个很自然的想法将该类型的对象作为参数,像这样:  Sample (Sample a);  不幸的,即使这样朴实无华的声明也隐含了一个微妙的错误,呵,...
  • 拷贝构造函数的形参必须是引用,这是编译器强制规定的,否则不能编译通过。 为什么? 调用拷贝构造函数的三种情况 用已知的对象拷贝生成新对象 以值传递的方式传入函数 函数的返回值是以值传递的方式 形参为...
  • (1)我传的asd1不是个临时对象,为什么需要const? (2)看不出复制构造函数为什么效率比移动构造函数低。 (3)我想把对象本身加到vector中,但是不能以引用形式传?只能用指针? 用的VS2010的编译器。 求...
  • 在C++中, 构造函数,拷贝构造函数,析构函数和赋值函数(赋值运算符重载)最基本不过的需要掌握的知识。 众所周知,c++中类没有给出复制构造函数的话,编译器会自动补上一个,然而对于深拷贝来说编译器给的复制...
  • 什么x必须是final? interface AnnoInner { void addXYZ(); } public class classOuter { public static void main(String[] args) { // TODO Auto-generated method stub } public ...
  • 形参和实参是什么?? 实参(argument):  全称为"实际参数"是在调用时传递给函数的参数. 实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值...
  • double cube(double x) { return x*x*x; } void main() { double m;...1.实参可以是常量,变量,表达式,函数等,但都必须是确定的值。 2.形参用于接收实参值的变量。 3.参数传递的过程:将实参的e值赋
  • 它们都有什么用呢?其实通俗点讲,将一个椅子放进一个小房间锁上门,你若想拿出凳子,就必须有锁门的钥匙,而这钥匙就是指针。举一个简单的例子:int a = 3;int *p;p = &a;p就是一个指针,通过它就能打开a这扇门...
  • 什么是函数:程序中专门保存一段可重用的代码片段的程序结构,再起一个名字。 为什么要使用函数:代码重用 何时使用函数:只要一段代码...为什么要使用形参变量:有些函数执行时,必须传入必要的数据,才能正常的执行。
  • C++ 形参为什么加入const 什么鬼? 本文参考博客:... 出错纠正:右图中形参前加上 const 即可。 ... 总结congst:形参里限定为const表明传入的形参必须为常量也就以为着传入的参数不能被改变这一种保...
  • 在《C++ primer》中文第四版中...为什么形参必须为该类类型的引用?而不能值传递方式?(PS:其实传值和传址都可以统一为传值,前者传的对象的值,后者传的对象的地址的值) 先看下边两组代码: 1、 1 c...
  • 什么叫实参 形参 怎么用 区别

    千次阅读 2007-06-19 08:39:00
    形参和实参的类型必须要一致,或者要符合隐含转换规则, 当形参和实参不是指针类型时,在该函数运行时,形参和实 参不同的变量,他们在内存中位于不同的位置,形参将实 参的内容复制一份,在该函数运行结束的时候形参被...
  • 那么这些到底是什么呢?下面我们就来详细的说一下函数的参数和变量的问题。参数 & 变量我们用 def 来定义函数,函数名后面的括号里如果有变量的话,它们通常被成为「形参」;在我们调用的时候,给函数提供的值...
  • 在这里我们看到使用匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一个接口。同时它也没有class关键字,这因为匿名内部类直接使用new来生成一个对象的引用。当然这个...
  • 实参和形参

    2019-10-27 21:09:31
    今天研究了一下什么是形参和实参。 实参 全称为"实际参数"在调用时传递给函数的参数. 实参可以常量、变量、表达式、函数等, 无论实参何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些...
  • 一、使用匿名内部类内部类 匿名内部类由于没有名字,所以它的...在这里我们看到使用匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一个接口。同时它也没有class关键字,这...
  • 你如何决定在什么时候使用指针,在什么时候使用引用呢?  首先,要认识到在任何情况下都不能用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候...
  • 那这什么呢?不急,我们首先来看第一个知识点。知识点一,匿名内部类同所有类一样,都有构造函数的,只不过这个构造函数隐式的,虽然内部类,但是经过编译之后,JVM还是会为匿名内部类生成...
  • 什么是形参什么是实参 注意点 实参值(变量值)与形参(变量名)的绑定关系只在函数调用的时才会生效\绑定,当函数调用结束后,立刻解除绑定 什么是位置参数 1位置形参(定义时)调用时必须为其传值,不能...
  • 因为内部类中的属性的改变不会影响外部的形参,然而,这从程序员角度来看不可行的,站在程序员的角度看,这两个根本就是一个,如果内部类改变了,而外部方法的形参却没有改变难以理解和不可接受的,为了保持参数...
  • 我们观察到在类中定义方法时,都带有self形参,为何必须在方法中定义形参self呢?因为Python调用方法创建类实例时,将自动传入实参self。每个与类相关联的方法调用都自动传递实参self,他一个指向实例本身的引用,...
  • #define _CRT_SECURE_NO_WARNINGS #include using namespace std; //等号运算符的重载 ...源码如上,其中编译正确,却运行不了,如果把类中的构造函数的形参的默认赋值等于零,则正确,但是不知道为什么呢?
  • 关于函数调用时形参与实参的情况

    千次阅读 2020-03-01 00:46:18
    首先什么是形参与实参 形式参数:定义函数时函数名后括号中的变量名! 实际参数:调用函数时函数名后括号中的表达式! 1.形参未被调用时,不占存储单元。形参只在调用过程中占用存储单元。形参定义时必须指定类型! ...
  • c++ 中函数形参没有变量名

    千次阅读 2019-11-03 16:14:00
    这一看,不知道是什么意思,为什么形参没有参数名? 正常的情况应该是这样的 int add(int a,int b); 这是由于没有形参名的函数只用来声明,然而到定义的时候,必须有形参名称。类似这样: int add(int, int); int ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 509
精华内容 203
关键字:

形参必须是什么