精华内容
下载资源
问答
  • 复制构造函数的作用

    2020-04-15 15:59:17
    #include using namespace std; class tank { public: ...//注意,构造函数前无标识符 ~tank(); tank(const tank & vehicle); void showinfo(); private: double tanklegth; double tankwidth...

    #include
    using namespace std;
    class tank
    {
    public:
    tank(double x,double y,double z);//注意,构造函数前无标识符
    ~tank();
    tank(const tank & vehicle);
    void showinfo();
    private:
    double tanklegth;
    double tankwidth;
    double tankheight;
    };
    tank::tank(double x=0,double y=0,double z=0)//构造函数定义,其作用是初始化
    {
    tanklegth=x;
    tankwidth=y;
    tankheight=z;
    }
    tank::tank(const tank & vehicle)//(引用号"&"后面接的是 复制构造函数的)
    {
    tanklegth=vehicle.tanklegth10+vehicle.tankwidth;//赋值构造函数可以对数据成员进行加减数值运算
    tankwidth=vehicle.tankwidth
    100;
    tankheight=vehicle.tankheight1000;
    double volumn=tanklegth
    tankwidth*tankheight;
    }
    //复制构造函数中,可以对数据成员进行其他处理,表示我引用了构造函数,在复制构造函数中,进一步操作,此时构造函数不变。
    tank::~tank()
    {
    }
    void tank::showinfo()
    {
    cout<<“坦克长为”<<tanklegth<<endl;
    cout<<“坦克宽为”<<tankwidth<<endl;
    cout<<“坦克高为”<<tankheight<<endl;

    }
    #include"point.h"
    void main()
    {
    double length,width,height;
    cout<<“请输入坦克长宽高”<<endl;
    cin>>length>>width>>height;
    tank p1(length,width,height);
    p1.showinfo();
    tank p2(p1);//赋值构造函数
    p2.showinfo();
    }
    //一个简单的复制构造函数,其作用是对数据成员进行操作,类似于函数的作用,而构造函数仅仅是为了给数据成员进行初始化。当然,数据成员的操作也可以通过成员函数进行。

    展开全文
  • 我们什么时候需要一个复制构造函数我的意思是我们需要使用复制构造函数的确切情况或场景.有人可以用一个例子来解释,或者指出一些链接,以便我能够清楚地了解它们.以下是我经历的链接,以了解什么是复制构造函数.第二个...

    我正在通过复制构造函数,我已经通过流程和其他的堆栈链接.但我不清楚以下几点.

    >为什么我们需要一个复制构造函数

    >我们什么时候需要一个复制构造函数

    我的意思是我们需要使用复制构造函数的确切情况或场景.有人可以用一个例子来解释,或者指出一些链接,以便我能够清楚地了解它们.

    以下是我经历的链接,以了解什么是复制构造函数.

    第二个链接解释了使用复制构造函数的“为什么”和“在哪里”.但是我还不清楚.

    下面是我的类Employee.java

    package com.test;

    /**

    * @author avinashd

    *

    */

    public class Employee {

    private String rollNo;

    private String name;

    //constructor

    public Employee(String rollNo, String name){

    this.rollNo = rollNo;

    this.name = name;

    }

    //copy constructor

    public Employee(Employee employee){

    this.rollNo = employee.rollNo;

    this.name = employee.name;

    }

    public String getRollNo() {

    return rollNo;

    }

    public void setRollNo(String rollNo) {

    this.rollNo = rollNo;

    }

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    }

    Copy Constructor用于创建具有相同现有对象值的对象的精确副本.

    比方说我们有一个雇员的值为rollNo:1,名称为avinash. Copy Constructor将创建一个类似的对象,值为rollNo:1,名称为:avinash.但是两个都是两个不同的对象,而对对象的值的更改不会影响另一个对象.

    这里的问题是

    当我们有一个构造函数,如

    public Employee(String rollNo, String name){

    this.rollNo = rollNo;

    this.name = name;

    }

    创建一个对象.我们可以调用同一个构造函数来创建另一个对象.但是为什么我们需要调用copy构造函数呢?我们需要调用它吗?请解释

    展开全文
  • Qt中为什么函数可以直接返回...注:本文涉及到的主要知识点为:C++的复制构造函数的作用 一、在C++中返回参数的基础知识 在C++中,函数返回类型有,基本数据类型,结构体,对象,指针。下面举例几个正确使用C++...

    Qt中为什么函数可以直接返回QImage/QString对象,而不是QImage* QString*(指针)

    副标题:C++编程中使用List<Object*>还是List<Object>呢 ?

    注:本文涉及到的主要知识点为:C++的拷贝构造函数的作用

    一、在C++中返回参数的基础知识

    在C++中,函数返回类型有,基本数据类型,结构体,对象,指针。下面举例几个正确使用C++中函数返回值的使用方法:

    1. 返回c++基本类型
      int max(int a, int b) {
      return a > b ? a : b;
      }
    2. 返回指针:返回的指针所指的对象必须是用new生成的。
      优点:返回指针,加快了参数传递速度
      缺点:new需要花费不少时间
      优点:在单实例模式需要使用这个方式
      Apple *GetAnApple() {
      Apple *apple*= new Apple();
      return apple;
      }
    3. 返回对象:直接返回对象,在return的时候会调用类的拷贝构造函数,给返回值赋值,然后函数内的局部变量就会被销毁。
      缺点:1.返回前还要调用类的拷贝构造函数新建并复制全部成员变量。计算压力增大。
      缺点:2.在类的成员变量中包含静态成员或指针成员的时候需要自己实现拷贝函数,默认的拷贝构造函数会导致错误;参考:https://blog.csdn.net/lwbeyond/article/details/6202256
      Banana GetABanana() {
      Banana banana;
      return banana;
      }
    4. 返回引用:这个是错误的不可用的,局部变量在函数执行完会被销毁。因此返回局部变量的引用是不可行的。高级点的编辑器在你这样写的时候就会提示错误。
      Banana& GetABanana() {
      Banana banana;
      return banana;
      }

    二、在C++中可以直接返回String对象或QImage对象

    1. 为什么要直接返回对象
      由于“一.3 返回对象”可知直接返回对象是可行的。但是为什么要设计为允许返回一个对象呢,字符串很大时候,复制一个字符串很浪费内存。同理在Qt中返回QImage对象也非常浪费内存,为什么要这样设计呢?

    2. 原因梳理
      一般使用方法
      String GetAStr() {
      String a = “1”;
      return a;
      }
      String b = GetAStr();
      但是人家这样设计了肯定是有原因的。原因如下:
      返回对象肯定用到了QString类的拷贝构造函数,但是了避免把字符也再次复制一遍,应该是用了指针指向同一份“字符串”,因此在拷贝构造函数只要复制指针的值即可。因此直接返回String对象是可行的,返回对象并不会浪费内存。同理返回QImage也是这样的原理。

    3. 官方文档给出的解释
      在Qt的QImage文档中看到如下内容:
      “QImage objects can be passed around by value since the QImage class uses implicit data sharing.”
      翻译:QImage对象可以当成值直接传递,因为QImage的实现使用了“隐式数据分享”
      关于Qt的“隐式数据分享”核心介绍文字如下:
      Many C++ classes in Qt use implicit data sharing to maximize resource usage and minimize copying. Implicitly shared classes are both safe and efficient when passed as arguments, because only a pointer to the data is passed around, and the data is copied only if and when a function writes to it, i.e., copy-on-write.
      A shared class consists of a pointer to a shared data block that contains a reference count and the data.
      翻译:在Qt中很多C++类使用隐式数据共享来最大化利用现有资源避免了复制数据。隐式分享在作为参数传递的时候具有安全和效率,因为传递的内容只有一个指向数据的指针。只有当一个函数修改了被指向数据的内容,才进行真正的数据拷贝(写时复制)。

    一个共享类由一个指向共享数据块的指针组成。这个共享数据块包含实际数据和这个数据被引用的次数。

    详情:https://doc.qt.io/qt-5/implicit-sharing.html
    Qt中使用了隐式数据分享的类有:QJsonArray,QList,QString,QImage,QPen,QHostAddress等,详情表在以上详情链接里面有。

    三、在定义对象列表的时候使用List<Apple>还是List<Apple*>好呢?

    添加数据时候的区别:
    “//———————List<Apple>”
    Apple a;//局部变量初始化消耗时间,消耗栈内存
    List.appene(a);//添加到列表需要调用类的拷贝构造函数,需要消耗复制成员变量的时间,(或处理自定义拷贝构造函数的时间,如果使用自定义拷贝构造函数)
    “//———————List<Apple*>”
    Apple *a = new Apple();//采用new内存需要消耗时间,消耗堆内存
    list.append(a);

    从以上分析可知:

    1. 内存使用:new一个对象和初始化一个局部变量所消耗的内存与cpu计算量相差无几。
    2. 添加速度:
      2.1 添加一个List<Apple>项目需要的时间包括:新建局部变量,初始化变量,拷贝构造对象。
      2.2 添加一个List<Apple*>项目需要的时间包括:申请内存新建变量,初始化变量。(这个两个速度无法预估,没有做实际测试)
    3. 访问速度:C++访问对象也是用指针访问,访问指针对象也是指针访问,因此调用List的Item的时候速度也相差无几。
    4. 功能限制:使用List<Apple>的时候需要使用类的拷贝构造函数,因此就有了限制,自己不写拷贝构造函数,c++编译器会提供隐式拷贝构造函数。但是当类里面有静态成员变量或指针成员变量的时候,编译器提供的隐式拷贝构造函数就会造成程序错误。因此需要显式编写拷贝构造函数的代码。(这点比较重要)使用List<Apple*>的时候,没有拷贝构造函数的限制。

    从以上分析可以得到以下结论:

    1. 使用List<Apple*>会使得代码简洁,容易编码,初学者也可以编写出正确稳定的代码(因为不用考虑是否需要编写自己的拷贝构造函数,以及具体编写)。
    2. 在使用特定的类的时候比如QString的时候,直接返回对象是更有优势的,避免了(new、delete)自己做内存管理。
    • 注1:在Java中使用了List<Apple>的格式但是其实相当于C++的List<Apple*>。(java表面没有指针的概念和语法,但是内在都是用了指针的思想和实现)
    • 注2:一般设计C++应用程序的时候,为了避免隐式调用拷贝构造函数而引起的问题。一般都显式指定一个私有的拷贝构造函数。(同理,指定一个显式私有赋值构造函数)。在qt中的方法为:private:Q_DISABLE_COPY(Class) ,这个宏定义的实现为:
      #define Q_DISABLE_COPY(Class)
      Class(const Class &) Q_DECL_EQ_DELETE;\ //拷贝构造函数
      Class &operator=(const Class &) Q_DECL_EQ_DELETE; //赋值构造函数
    展开全文
  • 函数的形参是类A的对象(非引用),该函数被调用时,该类的复制构造函数被调用。 某函数的返回值是类A的对象(非引用),该函数返回时,该类的复制构造函数被调用。 注意,对象间“赋值”并不引起复制构造...
    1. 当用一个对象去初始化同类的另一个对象时:
      Complex c2(c1);
      
      Complex c2 = c1;

       

    2. 某函数的形参是类A的对象(非引用),该函数被调用时,该类的复制构造函数被调用。

    3. 某函数的返回值是类A的对象(非引用),该函数返回时,该类的复制构造函数被调用。

    注意,对象间“赋值”并不引起复制构造函数被调用。

    Complex a1, a2;
    a2 = a1;//不会引起复制构造函数调用


    #include <iostream>
    using namespace std;
    class Sample {
    public:
        int v;
        Sample(int n = 0)
        {
            v = n;
        }
        Sample(const Sample& x)
        {
            v = x.v + 2;
        }
    };
    void PrintAndDouble(Sample o) //作为函数参数时候会调用复制构造函数
    {
        cout << o.v;
        cout << endl;
    }
    int main()
    {
        Sample a(5);
        Sample b = a;//调用复制构造函数
        PrintAndDouble(b);
        Sample c = 20;
        PrintAndDouble(c);
        Sample d;
        d = a;
        cout << d.v;
        return 0;
    }

    输出

    9

    22

    5


    更新:

    当我们设计class时,必须问问自己,在此class之上进行“成员逐一初始化”的行为模式是否适当?如果答案肯定,我们就不需要另外提供copy constructor。但如果答案是否定的,我们就必须另行定义copy constructor,并在其中编写正确的初始化操作。(当浅复制发生错误时手动实现深复制)!

    展开全文
  • 构造函数、复制构造函数和析构函数是C++类中默认
  • C++复制构造函数作用的三种情况: 1)当用一个对象去初始化同类另一个对象时 Complex c2(c1); //和下面那一句等价 Complex c2 = c1;//这里是初始化!不是赋值! //但是如果是如下就不调用赋值构造函数 Complex ...
  • 复制构造函数

    2020-05-11 23:54:36
    复制构造函数的作用: 使用一个已经存在的对象初始化一个同类的新对象。 复制构造函数的特点: 复制构造函数名与类名相同,并且也没有返回值类型(被系统自动调用)。 复制构造函数可写在类中,也可以写在类外。 ...
  • 复制构造函数和合成复制构造函数 复制构造函数 复制构造函数又称为拷贝构造函数,它是一种特殊的构造函数。它的作用就是用一个已经生成的对象来初始化另一个另一个同类的对象 变量的初始化: int a=10;int b=a; ...
  • 构造函数的作用:在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态。  构造函数的性质:构造函数的函数名与类名相同,没有返回值  一般存放在公有类型中;  例: class people {  public:  ...
  • 复制构造函数的作用 复制函数是为了将一个对象初始化或者赋值 用法一 声明一个对象的时候,往往用默认赋值操作符=或者默认复制构造函数来初始化; int a=6; int b=a;//默认复制操作符 in c(a);//默认复制构造函数 ...
  • 1.复制构造函数 复制构造函数又称为拷贝构造函数, 它是一种特殊的构造函数。 它的作用就是用一个已经生成的对象来初始化另一个同类的对象。 变量的初始化: int a=10; int b=a; 对象的初始化: Point pt1(10,20); ...
  • 复制构造函数作用的三种情况: 当用一个对象去初始化同类另一个对象时 如 Test a1=a2,区别于赋值 Test a1,a2;a1=a2; 如果某函数有一个参数是类 A 对象,那么该函数被调用时,类A复制...
  • 一、复制构造函数定义 ...对象名)//复制构造函数的实现 { 函数体 } 二、复制构造函数被调用的三种情况 定义一个对象时,以本类另一个对象作为初始值,发生复制构造; 如果函数的形参是类的对象,调用函数时,将使用
  • 该类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数,由构造函数完成成员的初始化工作,故:构造函数的作用:初始化对象的数据成员。 构造函数的种类 class Complex { private : double m_re.....
  • 该类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数,由构造函数完成成员的初始化工作,故:构造函数的作用:初始化对象的数据成员。 构造函数的种类 1 class Complex 2 { 3 4 ...
  • 复制构造函数与拷贝构造函数

    千次阅读 2014-09-16 11:39:03
    对于我来说,在写代码的时候能用得上复制构造函数的机会并不多,不过这并不说明复制构造函数没什么用,其实复制构造函数能解决一些我们常常会忽略的问题。  为了说明复制构造函数作用,我先说
  • 一、构造函数的作用 1.在对象被创建时使用特定的值构造对象,将对象初始化为一个特定的初始状态。 2 例如: 希望在构造一个Clock类对象时,将初试时间设为0:0:0,就可以通过构造函数来设置。 二、构造函数的形式 ...
  • 构造函数的作用: 1) 创建对象; 2) 初始化其值; 构造函数所具有的的特性: 1) 构造函数的函数名与类名相同; 2) 没有返回值; 构造函数的执行顺序: 1) 传参; 2) 按照类中成员变量声明顺序,依次构造其成员; 3) ...
  • 1、默认构造函数(默认值)构造函数的作用:初始化对象的数据成员。 2、复制构造函数 作用:用已存在的对象初始化新建的对象的数据成员。 类对象作为形参,如果参数是引用传递则不会调用任何复制构造函数;如果是...
  • 复制构造函数和类组合

    千次阅读 2012-08-31 20:33:46
    复制构造函数的作用:使用一个已经存在的对象(由复制构造函数的参数指定),去初始化同类的一个新对象。如果系统没有复制构造函数,系统会自动生成一个隐含的复制构造函数。 例: #include using namespace std...
  • 该类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数,由构造函数完成成员的初始化工作,故:构造函数的作用:初始化对象的数据成员。 构造函数的种类 1 class Complex 2 { 3 4 private...

空空如也

空空如也

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

复制构造函数的作用