条款5:了解c++默默编写并调用了哪些函数

 如果你不自己声明,编译器会替你声明(编译器版本的)拷贝构造函数、拷贝赋值运算符和析构函数。此外,如果你没有声明任何构造函数,编译器会为你声明一个默认构造函数。

class Empty{
   };

本质上和写成下面这样是一样的:

class Empty {
   
public:
Empty() {
    ... } 			// 默认构造函数
Empty(const Empty& rhs) {
    ... } 	// 拷贝构造函数
~Empty() {
    ... } 			// 析构函数

Empty& operator=(const Empty& rhs) {
    ... } // 拷贝赋值运算符
};
  • 默认构造函数和析构函数主要为编译器提供了一个放置“幕后”代码的地方,例如调用基类和非静态数据成员的构造函数和析构函数。
  • 拷贝构造函数和拷贝赋值运算符:编译器生成的版本只是简单地将源对象的每个非静态数据成员拷贝到目标对象。
     只要我们自己定义的类中存在构造函数,编译器就不会默认为我们提供构造函数,如下:
template<typename T>
class NamedObject {
   
public:
    NamedObject(const char* name, const T& value);
    NamedObject(const std::string& name, const T& value);
    ...
private:
    std::string nameValue;
    T objectValue;
};

NamedObject<int> no1("Smallest Prime Number", 2);
NamedObject<int> no2(no1); // 调用拷贝构造函数

如果我们的类中存在以下情况:存在引用或者常量的情况,编译器可能拒绝为你的类生成相应的代码。
在这里插入图片描述
我们可以看到报错了,这时候我们需要自己实现。

#include <iostream>

template<class T>
class NamedObject {
   
public:
    // 这个构造函数不再接受常量名称,因为nameValue现在是非常量字符串的引用。
    NamedObject(std::string& name, const T& value):nameValue(name), objectValue(value)
    {
   

    }
    // 和以前一样,没有声明operator=
    void operator=(const NamedObject& item)
    {
   
        this->nameValue = item.nameValue;
    }

    void printInfo();
private:
    std::string& nameValue; 	// 现在这里是引用
    const T objectValue; 	// 现在这里是常量
};

template<class T>
void NamedObject<T>::printInfo()
{
   
    std::cout << "name:" << nameValue << "  age:" << objectValue << std::endl;
}
int main()
{
   
    std::string newDog("Persephone");
    std::string oldDog("Satch");
    NamedObject<int> p(newDog, 2); 	// Persephone, 2岁
    NamedObject<int> s(oldDog, 36); 	// Satch,36岁
    p.printInfo();
    p = s; // p中的数据成员应该如何处理?
    p.printInfo();
}

在这里插入图片描述
 最后一种需要注意的情况,如果基类的拷贝赋值运算符声明为private,它的派生类将无法生成拷贝赋值运算符,因为无法调用基类部分的函数处理基类部分。
编译器可以隐式地生成类的默认构造函数、拷贝构造函数、拷贝赋值运算符和析构函数。

相关推荐

  1. 【More Effective C++】24:了解函数的成本

    2023-12-17 23:38:04       53 阅读
  2. effective c++ 笔记 5-12

    2023-12-17 23:38:04       57 阅读
  3. 09:绝不在析构和构造中调用virtual函数

    2023-12-17 23:38:04       38 阅读
  4. 《Effective C++》33

    2023-12-17 23:38:04       60 阅读
  5. 《Effective C++》37

    2023-12-17 23:38:04       59 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-17 23:38:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-17 23:38:04       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-17 23:38:04       87 阅读
  4. Python语言-面向对象

    2023-12-17 23:38:04       96 阅读

热门阅读

  1. 从零开始搭建Go语言开发环境

    2023-12-17 23:38:04       63 阅读
  2. gdb print,gdb x和gdb display的使用

    2023-12-17 23:38:04       68 阅读
  3. Spring Boot注解说明

    2023-12-17 23:38:04       56 阅读
  4. 【.Net 6.0--通用帮助类--ConvertHelper】

    2023-12-17 23:38:04       48 阅读
  5. gd32F303串口接收的几种方式

    2023-12-17 23:38:04       50 阅读
  6. 深度学习之模型权重

    2023-12-17 23:38:04       70 阅读