首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++基础-类和对象

声明构造函数时务必考虑使用关键字 explicit,以避免隐式转换。 务必将类成员声明为 std::string 和智能指针类(而不是原始指针),因为它们实现了复制构造函数,可减少您的工作量。...将 Copy() 返回值作实参,再次调用复制构造函数 return 0; } 上例中,参考注释,实例化 sayHelloAgain 对象时,复制构造函数被调用了两次。...如果对象很大,两次复制造成的性能影响不容忽视。 为避免这种性能瓶颈, C++11 引入了移动构造函数。...增加移动构造函数后,上一示例中,将首先调用移动构造函数,然后调用复制构造函数,复制构造函数只被会调用一次。 3. 析构函数 析构函数在对象销毁时被调用。执行去初始化操作。...为禁止赋值,可将赋值运算符声明为私有的。复制构造函数和赋值运算符声明为私有的即可,不需要实现。这样,如果代码中有对对象的复制或赋值,将无法编译通过。

98620

当类构造与析构的时候...

关于虚函数部分不在这篇再提,上一篇提过了。 文章目录 什么时候会调用默认构造函数 什么时候调用拷贝构造函数? 什么时候调用赋值运算符? 深拷贝与浅拷贝 成员初始化列表的概念,为什么用它会快一些?...NRV优化,但是由于返回方式是值传递,所以会在返回值的地方调用拷贝构造函数 ---- 什么时候调用赋值运算符?...赋值运算符是执行某种运算,将一个对象的值复制给另一个对象(已经存在的)。调用的是拷贝构造函数还是赋值运算符,主要是看是否有新的对象实例产生。...---- 深拷贝与浅拷贝 浅复制 :只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了...用初始化列表会快一些的原因是,对于类型,它少了一次调用构造函数的过程,而在函数体中赋值则会多一次调用。而对于内置数据类型则没有差别。

64520
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【C++】类和对象(中)

    构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有 一个合适的初始值,并且在对象的生命周期内只调用一次 特性 构造函数是特殊的成员函数,需要注意的是,...return 0; } 除此之外,如下的代码会造成二义性:(无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。...拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。...Func1(d1); Func2(d1); return 0; } 注意:如果我们没写拷贝构造函数,编译器会自动生成的默认拷贝构造函数的,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的...对于赋值重载(复制拷贝)和拷贝构造的区别: 赋值重载(复制拷贝) 已经存在两个对象之间拷贝 拷贝构造(初始化) 一个初始化另一个马上要创建的对象 赋值运算符主要有五点: 参数类型(如上的const

    1.2K30

    类与对象中篇

    构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每一个成员变量都有一个合适的初始值,并且在对象整个生命周期内只调用一次。...,为什么最后会调用Time类的析构函数?...但是:main函数 // 中不能直接调用Time类的析构函数,实际要释放的是Date类对象,所以编译器会调用Date类的析构函 // 数,而Date没有显式提供,则编译器会给Date类生成一个默认的析构函数...拷贝构造函数的特征: 1.拷贝构造函数是构造函数的一个重载形式。 2.拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。...注意:赋值运算符重载和拷贝构造的区别: 拷贝构造是用一个同类型的对象去初始化另一个对象,赋值运算符重载是两个对象已经存在,此时要将一个对象的值复制拷贝给另一个对象。

    52630

    C++避坑指南

    /a.out x = 2y = 1 如果我们需要指定依赖关系,比如y依赖x进行初始化,可以利用这样一个特性来实现:函数内部的静态对象在函数第一次调用时初始化,且只被初始化一次。...3.1 隐式转换 C++自定义类型在以下两种情况会发生隐式转换: 1) 类构造函数只有一个参数或除第一个参数外其他参数有默认值; 2) 类实现了operator type()函数;...上述String类存在到const char *的隐式转换,strcat函数返回时String隐身转换成const char *,而String对象已经被销毁,返回的const char *指向无效的内存区域...这也是std::string不提提供const char *隐式转换而专门提供了c_str()函数显示转换的原因。...shared_ptr sp(new Object());  这条语句会调用两次内存管理器,一次用于创建Object对象,一次用于创建控制块。

    1.6K30

    C++ explicit关键字详解

    = 10;” 这句为什么是可以的呢?...在C++中, 如果的构造函数只有一个参数时, 那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象....// 这样也是不行的, 因为取消了隐式转换, 除非类实现操作符"="的重载 explicit关键字的作用就是防止类构造函数的隐式自动转换....上面也已经说过了, explicit关键字只对有一个参数的类构造函数有效, 如果类构造函数参数大于或等于两个时, 是不会产生隐式转换的,所以explicit关键字也就无效了...., explicit关键字依然有效, 此时, 当调用构造函数时只传入一个参数, 等效于只有一个参数的类构造函数, 例子如下: class CxString // 使用关键字explicit声明

    8.9K40

    C++11 lambda

    lambda和functor的函数调用执行的代码是相同的。唯一的区别是lambda的构造函数被内联到创建lambda的函数中,而不是像函子的构造函数那样是一个单独的函数。...与按值捕获一样,functor和lambda调用代码是等价的,但是lambda的构造函数是内联的,而functor的则不是。 结论 C ++ lambda和函子比相似之处更多。...总结主要区别: 1、函子和lambda总是传递一个this指针,而普通函数自然不是。这会消耗一个额外的寄存器和8个字节的堆栈空间。 Lambda“构造函数”被内联到创建Lambda的函数中。...这显着减少了执行的复制量(lambda的2条指令,函子的5条指令),以及避免了函数调用的建立和拆卸。...在大多数情况下,“漏斗式”的普通函数已经完全可以满足需要了,但在某些特殊情况下,下一次的函数执行是在上一次函数执行的结果基础上进行的。这时,函数就需要记住上一次的执行状态数据以备下一次函数执行使用。

    1.1K30

    C++学习知识点

    : 主要是性能问题,对于内置类型,如int, float等,使用初始化类表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表,使用初始化列表少了一次调用成员的默认构造函数的过程...为什么函数形参多是const修饰的引用 使用引用是防止值传递,值传递之前会将实参在堆栈产生一份拷贝,而引用则不会,因此引用传递会改变实参的值。...(2) 当函数的参数为类的对象时,这时调用此函数时使用的是值传递,也会产生对象的复制。...(3) 函数的返回值是类的对象时,在函数调用结束时,需要将函数中的对象复制一个临时对象并传给改函数的调用处。 12....对于类定义对象什么时候用new,什么时候不用new的认识 (1) 构造函数只适用于类成员的初始化,与分配类对象的空间无关; (2) 隐式执行默认构造函数,初始化申明在栈上的类对象,直接申明,不要使用

    1.7K20

    对象的传值与返回

    在32处理器上,push指令一次只能压入4个字节的数据,那么对于long long就需要两次压栈指令了,而double类型参数就需要sub esp,8结合mov指令完成参数进栈的操作。...为此,我们定义一个简单的类A,为了防止编译器对我们的代码优化处理(参考我的前一篇博文),我们自己定义构造函数、复制构造函数和赋值运算符重载函数。...由于对象是值传递方式,因此,对象传递之前需要进行一次对象拷贝(从原对象到实参)。函数调用结束后还需要将返回值对象进行一次拷贝。我们看看VS2010的处理方式。 ?...而参数正是刚才fun调用结束后eax的值,因为它存储了返回值对象的地址。ecx记录this指针,正是被赋值对象的地址(a的地址)。赋值运算符重载函数调用结束后,完成返回值对象的赋值操作。...对象返回时,也需要将函数处理的结果进行一次对象拷贝,不过被拷贝的返回值对象内存已经在函数调用之前已经开辟出来了,函数只需要记录它的地址即可,然后调用拷贝构造函数初始化它。 3.

    2.5K80

    C++之类和对象

    默认构造 构造函数的第七个特性是:无参的构造函数和全缺省的构造函数都称之为默认构造函数,并且默认构造函数只能有一个。...拷贝构造 基础知识 复制是我们经常使用到的操作,如果想复制一个类的话该怎么办?C++对于这个问题的解决方案是提供了一种叫做拷贝构造的成员函数。...拷贝构造也是特殊的成员函数,其特征如下: 1.拷贝构造函数是构造函数的一个重载形式,当我们使用拷贝构造实例化对象时,编译器不再调用构造函数; 2.拷贝构造函数的参数只有一个且必须是类类型对象的引用,...; 引用做参数 拷贝构造的第二个特性说拷贝构造函数的参数必须是引用,否则会有无穷递归的现象产生,这是因为传值传参本身就是一次拷贝(传值传参是建立一个临时变量,然后将值拷贝给这个临时变量),而拷贝类就需要调用拷贝构造...,连续构造+拷贝构造->优化为直接构造 ** 可以看到这里只调用了一次构造函数,但是根据前面说的隐式类型转换我们可以知道中间有个临时变量的产生,需要先构造这个临时变量,再将这个临时变量拷贝构造aa,但编译器经过优化以后直接成了将

    1.2K00

    【C++修炼之路】3. 类和对象(中)

    ,为什么最后会调用Time类的析构函数?...拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用 为什么传值会无穷递归呢?...),发现在调用Func1时同时也调用了拷贝构造函数,而Func2却没有。...: 通过这个逻辑不难发现,每一次调用这个拷贝构造函数之后都会将传的值拷贝到拷贝构造函数的参数,而这个过程又会进入到下一层拷贝构造函数,就这样永无止境。...但在这里,我们还需要思考一些问题: 传值传参是一次拷贝构造,传返回值也是一次拷贝构造,因此为了提升性能我们采用传引用返回。那么为什么返回*this能传引用呢?

    52200

    类与对象(中)

    构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。...无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。...,为什么最后会调用Time类的析构函数?...拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错, 因为会引发无穷递归调用。...} 注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。

    7510

    类和对象之六大基础函数

    构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证 每个数据成员都有 一个合适的初始值,并且在对象整个生命周期(类的作用域)内只调用一次。...可能是考虑到向前兼容吧,反正大佬的世界我也不懂 doge)。 7. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。...拷贝构造函数的参数只有一个且必须是“类”类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用(为啥看下文)。...,为什么最后会调用Time类的析构函数?...但是: //main函数 // 中不能直接调用Time类的析构函数,实际要释放的是Date类对象,所以编译器会调用Date //类的析构函 // 数,而Date没有显式提供,则编译器会给Date类生成一个默认的析构函数

    57520

    C++11——对象移动与右值引用

    vector是一个常用的容器了,我们可以很容易的分析这这两次拷贝构造的时机: (1)第一次是在函数foo中通过临时Obj的对象Obj()构造一个Obj对象并入vector中; (2)第二次是通过从函数...左值到右值引用的转换: 虽然不能直接将右值引用直接,但是我们可以显示地将一个左值转换为对应的右值引用类型。我们可以通过调用新标准库中的模板函数move来获得绑定到左值的右值引用。...为了让我们自己定义的类型支持移动操作,我们需要为其定义移动构造函数和移动赋值运算符。这两个成员类似对应的拷贝操作,即拷贝构造和赋值运算符,但它们从给定对象窃取资源而不是拷贝资源。...完成资源移动后,原对象不再保留资源,但移动构造函数还必须确保原对象处于可销毁的状态。 移动构造函数的相对于拷贝构造函数的优点:移动构造函数不会因拷贝资源而分配内存,仅仅接管源对象的资源,提高了效率。...v时,又发生了一次元素的拷贝,结果出现了无谓的两次元素拷贝,这严重降低了程序的性能。

    87020

    C#关键字常见面试题

    静态构造函数只调用一次,在程序所驻留的应用程序域的生存期内,静态类会保留在内存中(即使用Static修饰的类,应用一旦启用静态类就会保留在内存中)。 静态类只包含静态成员 不能包含实例构造函数。...静态类不能包含实例构造函数。但是,它们可以包含静态构造函数。 静态成员和非静态成员的区别? 成员主要指的是:字段、方法、属性、运算符、事件和构造函数等。...this 关键字表示当前对象的引用,可以用于访问当前对象的成员。它可以用来区分局部变量和实例变量、在构造函数中调用其他构造函数、传递当前对象给其他方法等。 base 关键字有什么作用?...as运算符将表达式结果显式转换为给定的引用类型或可以为null值的类型。如果无法进行转换,则as运算符返回 null。...总结:as模式的效率要比is模式的高,因为借助is进行类型转换的化,需要执行两次类型兼容检查。而as只需要做一次类型兼容,一次null检查,null检查要比类型兼容检查快。 null是什么类型?

    17310

    C++10中的移动语义

    ,其实会调用两次拷贝构造函数。...第一次默认拷贝构造函数的调用是在demo对象的初始化过程中; 两次拷贝构造函数实在clone函数的调用过程中: clone函数中利用this对象初始化demo对象进行一个拷贝构造,然后返回demo...返回过程中会再次调用一次拷贝构造返回局部对象demo的一个拷贝。...对象的移动语义(Move Semantics)需要实现移动构造函数(move constructor)和移动赋值运算符(move assignment operator)。...如果源对象是在复制或者赋值结束以后被销毁的临时对象,编译器会使用两种方法。移动构造函数和移动赋值运算符将成员变量从源对象复制/移动到新对象,然后将源对象的变量设置为空值。

    50030

    c++标准模板库

    c_str   我们发现fopen函数只支持const char*类型(即C语言格式的字符串)的数据,此时就可以用c_str来转换。   ...这个时候我们就发现问题了,s1和s2在类里面定义的指针都指向了同一块空间,当程序结束时,s2析构函数释放空间,s1空间又释放了一次空间,一块空间被释放了两次,造成了程序崩溃。   ...s2 = "world"; //调用构造函数 String s3(s1); //调用拷贝构造函数 String s4 = s1; //调用拷贝构造函数...String s5; //调用构造函数 s5 = s1; //调用拷贝赋值运算符 return 0;...这是C++标准库里的swap()函数   我们看到,标准库里的方法要进行三次拷贝构造,且都是深拷贝。   而string类里的swap()函数只是简单进行值的交换,所以效率更高。

    53210

    类与对象(中)

    默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。 初始化和清理以及拷贝复制是最重要的。 析构函数不是在销毁对象,而是在清理空间。 2....函数名与类名相同。 2. 无返回值。(也不需要写void) 3. 对象实例化时编译器自动调用对应的构造函数。 4. 构造函数可以重载。(这里的重载指的是函数重载) 为什么构造函数支持函数重载?...d1是函数名,参数列表是空,返回值是Date。 7. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。...4.2 特征 拷贝构造函数也是特殊的成员函数,其特征如下: 1.拷贝构造函数是构造函数的一个重载形式。 2.拷贝构造函数的参数只有一个且必须是类类型对象的引用。...1.内置类型成员会完成浅拷贝/值拷贝 2.自定义成员会调用它的拷贝构造 注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。

    5210

    从基础入门到学穿C++(类和对象篇)【超详细】【一站式速通】

    如果每个对象都放成员函数,而这些成员函数却是一样的,浪费空间 ps:explicit关键字:用explicit修饰构造函数,将会禁止构造函数的隐式转换。...无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。 注意:默认的构造函数:不传参就可以进行调用。...拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。...我们在调用Func函数的时候,实参d1传值给了d,这里发生了拷贝构造,利用d1构造出了d。 运算符重载 自定义类型是不能用运算符的,要用就得实现运算符重载。..._day; } 运算符的重载是为了让自定义类型可以像内置类型一样去使用运算符。 拷贝构造是在对象创建的时候用另一个对象去初始化它,而赋值运算符重载是为了实现两个都已经初始化好的对象之间进行赋值。

    9910

    面试总结-C++

    ,但不能被模块外其他函数访问 在模块内的 static 函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内。...见为什么不能建立引用数组 将引用作为函数的参数时,可以避免对变量或者对象的复制,因此不会调用对象的拷贝构造函数。当不希望传入的引用参数不被改变时,使用const引用。...### 构造函数和析构函数 1.构造函数、析构函数中都不要调用虚函数 我们知道,构造函数一般不能是虚函数,而析构函数一般必须是虚函数。...7.保证构造、析构、swap不会失败 类型安全 与 线程安全 、异常安全、事务安全 其他 为什么说栈比堆要快 分配和释放:堆在分配和释放时都要调用函数(MALLOC,FREE),比如分配时会到堆空间去寻找足够大小的空间...访问时间,访问堆的一个具体单元,需要两次访问内存,第一次得取得指针,第二次才是真正得数据,而栈只需访问一次。 堆的内容被操作系统交换到外存的概率比栈大,栈一般是不会被交换出去的。

    2.1K11
    领券