C++构造函数+复制构造函数+重载等号运算符调用

目录
  • 前言:
  • 1、赋值和初始化的区别
  • 2、初始化和赋值分别调用哪个函数?
  • 3、编写测试类

前言:

初学C++发现了下面这个问题,其中Duck是一个已知的类,并以多种方式指定对象的值:

Duck d1();
Duck d2(d1);
Duck d3 = d1;
Duck d4;
d4 = d1;

问题在于,上述d1、d2、d3、d4是如何创建的呢?分别调用的哪个函数呢?

1、赋值和初始化的区别

C++中,赋值和初始化是两个不同的概念:

  • 初始化是指对象创建之时指定其初值,分为直接初始化和复制初始化两种(一句);
  • 赋值是指对象创建以后指定其值(两句);

对于上述d1、d2、d3、d4的创建来说,分别对应下述情况:

Duck d1();    // 直接初始化
Duck d2(d1);  // 复制初始化
Duck d3 = d1; // 复制初始化
Duck d4;      // 未初始化
d4 = d1;      // 赋值

2、初始化和赋值分别调用哪个函数?

直接初始化时,参数为对象所需的值,此时调用构造函数;复制初始化时,参数是一个已存在的类对象,此时调用复制构造函数;赋值时,对象是已经定义好的,调用“重载的等号赋值操作”,使用另一个对象的值计算出此对象的值。

Duck d1();    // 调用构造函数
Duck d2(d1);  // 调用复制构造函数
Duck d3 = d1; // 调用复制构造函数
Duck d4;      // 
d4 = d1;      // 赋值

需要特别注意的是下面两种方式都是初始化,而且都是调用的复制构造函数,容易误以为第二种方式是赋值:

Duck d2(d1);
Duck d3 = d1;

3、编写测试类

对于上述Duck类的初始化以及赋值方式,为了正确的测定每种情况分别调用了什么函数,下面的类中包含了构造函数、复制构造函数、重载等号赋值运算符函数:

class Duck{
public:
    Duck() { cout << "constructing !!!" << endl; };
    Duck(const Duck &d) { cout << "copying !!!" << endl; }
    Duck& operator=(const Duck &another);
};

Duck& Duck::operator=(const Duck &another) {
    cout << "operator= !!!" << endl;
    return *this;
}

使用Section 1Section 2中的各种方式指定对象的值时,可以方便的确定出各个函数的调用情况。

到此这篇关于C++构造函数+复制构造函数+重载等号运算符调用的文章就介绍到这了,更多相关C++函数调用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c++ 构造函数中调用虚函数的实现方法

    我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { public: A ():m_iVal(0){test();} virtual void func() { std::cout<<m_iVal<<' ';} void test(){func();} public: int m_iVal; }; class B : public A {

  • C++构造函数+复制构造函数+重载等号运算符调用

    目录 前言: 1.赋值和初始化的区别 2.初始化和赋值分别调用哪个函数? 3.编写测试类 前言: 初学C++发现了下面这个问题,其中Duck是一个已知的类,并以多种方式指定对象的值: Duck d1(); Duck d2(d1); Duck d3 = d1; Duck d4; d4 = d1; 问题在于,上述d1.d2.d3.d4是如何创建的呢?分别调用的哪个函数呢? 1.赋值和初始化的区别 C++中,赋值和初始化是两个不同的概念: 初始化是指对象创建之时指定其初值,分为直接初始化和复制初始化两

  • C++类继承之子类调用父类的构造函数的实例详解

    C++类继承之子类调用父类的构造函数的实例详解 父类HttpUtil: #pragma once #include <windows.h> #include <string> using namespace std; class HttpUtil { private: LPVOID hInternet; LPVOID hConnect; LPVOID hRequest; protected: wchar_t * mHostName; short mPort; string send

  • 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结

    1 . 用同一个类的源对象构造一个目标对象时,会调用拷贝构造函数来构造目标对象,如果没有定义拷贝构造函数,将调用类的默认拷贝函数来构造目标对象.2 . 当一个函数的返回值为一个类的对象时,如果在调用函数中,没有定义一个对象来接收这个返回对象值,会用返回一个临时对象保存返回对象的值.在被调用函数结束时,这个临时对象被销毁.而当调用函数中有一个接受对象时,就将返回对象赋值给接收对象,这个返回对象在调用函数结束时调用析构函数.3. 当类有一个带有一个参数的构造函数时,可以用这个参数同类型的数据初始化这

  • C++聚合关系类的构造函数的调用顺序详解

    如图,表示一个聚合关系 下面就用简单的代码来实现 #pragma once class Engine { public: Engine(); ~Engine(); }; Engine.h #include <iostream> #include "Engine.h" using namespace std; Engine::Engine() { cout << "调用构造函数:Engine()" << endl; } Engine

  • C++中构造函数与析构函数的调用顺序详解

    前言 在使用构造函数和析构函数时,需要特别注意对它们的调用时间和调用顺序.在一般情况下,调用析构函数的次序正好与调用构造函数的次序相反:最先被调用的构造函数,其对应的(同一对象中的)析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用. 简单来说,其构造函数的顺序就一句话: 基类构造函数 -> 成员的构造函数 -> 构造函数体内语句 看下面一个代码示例: #include <iostream> using namespace std; class A { publ

  • 浅谈C++中的构造函数分类及调用规则

    构造函数的分类 这里简单地将C++中的构造函数分一下类,直接看下面的代码表达,说明在注释中: #include <iostream> using namespace std; class Text { public: Text() // 无参数构造函数 { m_a = 0; m_b = 0; cout << "无参数构造函数" << endl; } Text(int a) // 有参数构造函数 { m_a = a; m_b = 0; cout <

  • 详谈C++何时需要定义赋值/复制构造函数

    继承和动态内存分配 假设基类使用了动态内存分配,而且定义了析构函数.复制构造函数和赋值函数,但是在派生类中没有使用动态内存分配,那么在派生类中不需要显示定义析构函数.复制构造函数和赋值函数. 当基类和派生类采用动态内存分配时,派生类的析构函数.复制构造函数.赋值运算符都必须使用相应的基类方法来处理基类元素.这种要求是通过三种不同的方式来满足的.对于析构函数.这是自动完成的,也就是说在派生类的析构函数中无需显示调用基类的析构函数.对于构造函数,这是通过在初始化成员列表中调用基类的复制构造函数来完成

  • C++中的复制构造函数详解

    目录 复制构造函数 复制构造函数的三种调用 复制构造函数的禁用 深拷贝与浅拷贝 一定会生成默认复制构造函数吗? 参考 总结 普通变量的复制 有时我们会在定义一个变量的同时使用另一个变量来初始化它. int a_variable=12; int new_variable(a_variable); 通过已有的同类型变量来初始化自身很有用. 对自定义类型的对象是否可以通过一个存在的对象方便的复制呢? 复制构造函数 复制构造函数又叫做拷贝构造函数,它只有一个参数(既然需要复制,一个就够了,若传入两个相同

  • C++中复制构造函数和重载赋值操作符总结

    前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符的实现要点: 4.复制构造函数的一些细节. 复制构造函数和重载赋值操作符的定义 我们都知道,在C++中建立一个类,这个类中肯定会包括构造函数.析构函数.复制构造函数和重载赋值操作:即使在你没有明确定义的情况下,编译器也会给你生成这样的四个函数.例如以下类: 复制代码 代码如下: class CTes

  • php中拷贝构造函数、赋值运算符重载

    对象的赋值与复制: 赋值:通过" = "运算符重载User a(10),b;b = a;复制:调用复制构造函数User b;User a(b);或者User a = b;//相当于User a(b);与赋值的区别,赋值是对一个已经存在的对象进行赋值(已经实现定义了被赋值的对象),而复制是从无到有建立一个新的对象,并使它与已有的对象相同.浅复制与深复制: 若对象中有指针成员,在复制时,只会将该指针成员的地址复制给新建立的对象,因此,两个对象中的指针成员都指向了同一块内存区域,在释放时会出

  • 关于C++复制构造函数的实现讲解

    复制构造函数是一种特殊的构造函数,有一般构造函数的特性.它的功能是用一个已知的对象来初始化一个被创建的同类对象.复制构造函数的参数传递方式必须按引用来进行传递,请看实例: #include <iostream> #include <cstring> using namespace std ; class Student { private : char name[8]; int age ; char sex ; int score ; public : void disp(); /

  • 详解c/c++赋值函数(重载=号运算符)

    首先c++里的各种运算符都是用函数实现的,比如=,就等号函数. 所以当用=给一个对象赋值的时候,实际调用的是=号所对应的=号函数. 分析下面的代码 #include <iostream> using namespace std; class Test{ public: explicit Test(){ data = 0; } explicit Test(int d):data(d){ cout << "C:" << this << &qu

  • javascript等号运算符使用详解

    本章节介绍一下javascript中等号运算符的用法,需要的朋友可以做一下参考. 等号运算符最为基本的用法就是比较两个运算数是否相等,看如下代码实例: 复制代码 代码如下: var a=2,b=2; console.log(a==b); 如果两个操作数相等,那么返回值就是true,否则返回false. 上面是最为基本的用法,下面再来介绍一下它相对比较特殊的几种情况. 复制代码 代码如下: var str="5"; var num=5; console.log(str==num); 上面

  • C#中重载相等(==)运算符示例

    运算符重载一直是一个很诡异事情,因为在写代码的时候,不知道某个运算符有没有被重载过.在 C++ 里面,运算符重载可以写在类的外面,当 intellisense 不工作的时候,找到一个运算符的重载函数是一件相当头疼的事情.这个问题在 C# 中改善了不少,因为运算符重载一定要写在类内,而且 intellisense 很强大.不过另一个问题又产生了-- 先来看 C++ 中的"=="重载: struct A{ int x; int y; }; inline bool operator == (

  • javascript 全等号运算符使用说明

    而以前一直都是用等号"=="一直都没在JS里用过全等于符号"===".而這两种运算符只是检测两个对象的相等性时,一个执行类型转换和一个类型不转换,全等于符号只有在不转换类型前才返回true 复制代码 代码如下: var sNum="66"; var iNum=66; alert(sNum==iNum);//输出为 true alert(sNum===iNum);//输出为 false 第一个等于运算符在比较的时候就把sNum的值"66&

随机推荐