C++中复制函数在三种情况下自动调用:

  1. 用一个对象初始化另一个对象
  2. 函数的参数为对象
  3. 函数的返回值为对象

下面用几个代码片段解释复制函数的调用中的一些常见“坑”:

一:默认复制函数的自动调用

 1 #include<iostream>
2 using namespace std;
3
4 class Point
5 {
6 public:
7 Point(int X, int Y) :x(X), y(Y) {};
8 void showCoordinate()
9 {
10 //展示坐标
11 cout << "X=" << x << "\tY=" << y << endl;
12 }
13 private:
14 int x;
15 int y;
16 };
17
18 int main()
19 {
20 Point p1(0, 0);
21 p1.showCoordinate();
22 Point p2 = p1; //此事并未编写显示的复制函数,系统会自动生成Point的一个自适应复制函数
23 p2.showCoordinate(); //发现 p2 的坐标与 p1 相同
24 cout << &p1 << endl;
25 cout << &p2 << endl; //显然,p2 只是 p1 复制函数之后的新的对象,在内存中的地址并不相同
26 return 0;
27 }

二:不存在合适的构造函数【实质上还是复制函数的问题】

#include<iostream>
using namespace std; class Point
{
public:
Point(int X, int Y) :x(X), y(Y) {};
Point(Point& p);
int getX() { return x; }
int getY() { return y; }
private:
int x;
int y;
};
Point::Point(Point& p) {
x = p.x;
y = p.y;
}
class Line
{
public:
Line(Point temp_p1, Point temp_p2) {
p1 = temp_p1;
p2 = temp_p2;
};
private:
Point p1;
Point p2;
}; int main()
{
Point p1(0, 0);
Point p2 = p1; //此时复制函数仍然可以正常调用,但是 24 行报错
/**
* C2512“Point” : 没有合适的默认构造函数可用
* E0291 类 "Point" 不存在默认构造函数
*/ return 0;
}

为什么出现这种情况,实质上是因为1:Line的构造函数中使用了无参数的构造函数,但是只有当没有编写构造函数时,系统会自动生成一个没有参数的构造函数,而编写了构造函数之后系统并不会自动生成。

一个治标不治本的方法是,在class Point中加入一个无参数的构造函数。但是问题显而易见,么有参数的构造函数并么有实际意义。所以只能通过类的组合,将Point类内嵌在Line类中。

将其改为:

Line(Point temp_p1, temp_p2) :p1(temp_p1), p2(temp_p2);

至此,可以编写计算线段长度的程序:

 1 #include<iostream>
2 #include<cmath>
3 using namespace std;
4
5 class Point
6 {
7 public:
8 Point(int X, int Y) :x(X), y(Y) {};
9 Point(Point& p);
10 int getX() { return x; }
11 int getY() { return y; }
12 private:
13 int x;
14 int y;
15 };
16 Point::Point(Point& p) {
17 x = p.x;
18 y = p.y;
19 }
20 class Line
21 {
22 public:
23 Line(Point temp_p1, Point temp_p2) : p1(temp_p1), p2(temp_p2) {};
24 double getLen();
25 private:
26 Point p1;
27 Point p2;
28 };
29
30 //计算线段长度,比较简单,可以设置为内联
31 inline double Line::getLen()
32 {
33 int a = abs(p1.getX() - p2.getX());
34 int b = abs(p1.getY() - p2.getY());
35 double len = sqrt(a * a + b * b);
36 return len;
37 }
38
39 int main()
40 {
41 Point p1(0, 0);
42 Point p2(3, 4);
43 Line line1(p1, p2);
44 cout << line1.getLen() << endl; //输出线段长度
45
46
47 return 0;
48 }

C++构造函数、复制函数易错点的更多相关文章

  1. python函数-易错知识点

    定义函数: def greet_users(names): #names是形参 """Print a simple greeting to each user in th ...

  2. python函数使用易错举例

    关于嵌套: 嵌套使用中,  retrun inner  ---> 返回的是函数的地址 retrun inner() :    --->  运行inner()函数   ---> 运行i ...

  3. 细节!重点!易错点!--面试java基础篇(二)

    今天来给大家分享一下java的重点易错点第二部分,也是各位同学面试需要准备的,欢迎大家交流指正. 1.字符串创建与存储机制:当创建一个字符串时,首先会在常量池中查找是否已经有相同的字符串被定义,其判断 ...

  4. 细节!重点!易错点!--面试java基础篇(一)

    今天来给大家分享一下java的重点易错点部分,也是各位同学面试需要准备的,欢迎大家交流指正. 1.java中的main方法是静态方法,即方法中的代码是存储在静态存储区的. 2.任何静态代码块都会在ma ...

  5. JavaScript易错知识点整理

    前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一 ...

  6. JavaScript易错知识点整理[转]

    前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一 ...

  7. js常见易错点

    原文:http://www.jianshu.com/p/1c77853d4f01 前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函 ...

  8. JavaScript 易错知识点整理

    本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES ...

  9. Java五道输出易错题解析(避免小错误)

    收集了几个易错的或好玩的Java输出题,分享给大家,以后在编程学习中稍微注意下就OK了. 1. 看不见的空格? 下面的输出会正常吗? package basic; public class Integ ...

随机推荐

  1. 关于cin, cin.get(), getchar(),getline()的字符问题

    一.getchar()和cin.get() getchar()会将开头的空格或者回车作为输入 1 #include<iostream> 2 using namespace std; 3 i ...

  2. linux系统中set、env、export关系

    set 用来显示shell变量(包括环境变量.用户变量和函数名及其定义),同时可以设置shell选项来开启调试.变量扩展.路径扩展等开关env 用来显示和设置环境变量export 用来显示和设置导出到 ...

  3. 把vscode打造成技术写作神器

    作为技术开发,大家平时肯定需要记录技术笔记.甚至有的同学还开通可自己的技术博客或者技术公众号进行创作. 这个时候有套趁手的写作工具尤为重要,节省下时间好好休息一下,对于咱们程序员来说更加重要.因为最近 ...

  4. 环境配置-Java-01-安装

    本文使用JDK1.8在windows64位系统下举例,其他版本在windows下的安装过程类似 0.百度云盘链接 考虑到官网下载需要登陆,这里给大家提供百度云盘链接(就是官网安装包),不过下载速度会比 ...

  5. 在nodejs中创建child process

    目录 简介 child process 异步创建进程 同步创建进程 在nodejs中创建child process 简介 nodejs的main event loop是单线程的,nodejs本身也维护 ...

  6. 容器化安装Mysql 8.0 并部署主从复制

    系统: Centos 7.4 数据库版本:8.0.20 两台机器做相同操作 安装Docker export VERSION=18.06 && curl -fsSL http://rai ...

  7. 夯实基础系列一:Java 基础总结

    前言 大学期间接触 Java 的时间也不短了,不论学习还是实习,都让我发觉基础的重要性.互联网发展太快了,各种框架各种技术更新迭代的速度非常快,可能你刚好掌握了一门技术的应用,它却已经走在淘汰的边缘了 ...

  8. IDEA_2019.1版本中Protobuf的使用

    一.Protobuf是什么 Protobuf 是 Google 发布的开源项目,全称 Google Protocol(/'prəʊtəkɒl/,协议,草案) Buffers,是一种轻便高效的结构化数据 ...

  9. LOJ10131暗的连锁

    题目描述 原题来自:POJ 3417 Dark 是一张无向图,图中有 N 个节点和两类边,一类边被称为主要边,而另一类被称为附加边.Dark 有 N–1 条主要边,并且 Dark 的任意两个节点之间都 ...

  10. Node.js躬行记(6)——自制短链系统

    短链顾名思义是一种很短的地址,应用广泛,例如页面中有一张二维码图片,包含的是一个原始地址(如下所示),如果二维码中的链接需要修改,那么就得发代码替换掉. 原始地址:https://github.com ...