C++基础知识:构造函数、复制构造函数与常量引用参数详解
创作时间:
作者:
@小白创作中心
C++基础知识:构造函数、复制构造函数与常量引用参数详解
引用
CSDN
1.
https://blog.csdn.net/m0_66847953/article/details/139009506
本文将详细介绍C++中的构造函数、复制构造函数以及常量引用参数的使用方法。通过本文的学习,读者将能够理解这些基础概念,并能够在实际编程中正确使用它们。
一、构造函数
基本概念
- 它是成员函数的一种,名字与类名相同,可以有参数,不能有返回值(void也不行)
- 作用是对对象进行初始化,如给成员变量赋初值
- 如果定义类时没写构造函数,则编译器生成一个默认的无参数的构造函数
- 如果定义了构造函数,则编译器不生成默认的无参数的
- 对象生成时构造函数自动被调用。对象一旦生成,就再也不能在其上执行构造函数
- 一个类可以有多个构造函数
为什么需要构造函数
- 构造函数执行必要的初始化工作,有了构造函数,就不必专门再写初始化函数,也不用担心忘记调用初始化函数。
- 有时对象没被初始化就使用,会导致程序出错。
class Complex {
private:
double real, imag;
public:
Complex(double r, double i = 0);
Complex::Complex(double r, double i) {
real = r;
imag = i;
}
};
Complex cl; // error,缺少构造函数的参数
Complex* pc = new Complex; // error,没有参数
Complex cl(2); // OK
构造函数可以有多个,参数个数和类型不同
class Test {
public:
Test(int n) {} //(1)
Test(int n, int m) {} //(2)
Test() {} //(3)
};
Test array1[3] = {1, Test(1, 2)}; // 三个元素分别用(1),(2),(3)初始化
Test array2[3] = {Test(2, 3), Test(1, 2), 1}; // 三个元素分别用(2),(2),(1)初始化
Test *pArray[3] = {new Test(4), new Test(1, 2)}; // 俩个元素分别用(1),(2)初始化
二、复制构造函数
基本概念
- 只有一个参数,即对同类对象的引用。
- 形如
X::X(X&)
或X::X(const X &)
, 二者选一后者能以常量对象作为参数 - 如果没有定义复制构造函数,那么编译器生成默认复制构造函数。默认的复制构造函数完成复制功能。
class Complex {
private:
double real, imag;
};
Complex c1; // 调用缺省无参构造函数
Complex c2(c1); // 调用缺省的复制构造函数, 将 c2 初始化成和c1一样
复制构造函数起作用的三种方式
- 当用一个对象去初始化同类的另外一个对象时。
Complex c2(c1); // 初始化语句
Complex c2 = c1; // 也是初始化语句,非赋值语句,和上面的等价
- 如果某函数有一个参数是类A的对象那么该函数被调用时,类A的复制构造函数将被调用。
class A {
public:
A() {};
A(A& a) {
cout << "constructor called" << endl;
}
};
void Func(A a1) {}
int main() {
A a2;
Func(a2);
return 0;
}
- 如果函数的返回值是类A的对象时,则函数返回时A的复制构造函数被调用:
class A {
public:
int v;
A(int n) {
v = n;
}
A(const A& a) {
v = a.v;
cout << 111111 << endl;
}
};
A Func() {
A b(4);
return b;
}
int main() {
cout << Func().v << endl;
return 0;
}
- 注意:对象间的赋值不会对赋值构造函数进行调用
class CMyclass {
public:
int n;
CMyclass() {};
CMyclass(CMyclass& c) {
n = 2 * c.n;
}
};
int main() {
CMyclass c1, c2;
c1.n = 5;
c2 = c1; // 对象间赋值
CMyclass c3(c1);
cout << "c2 .n=" << c2.n << "c3.n=" << c3.n << endl;
return 0;
}
输出结果:
三、常量引用参数的使用
void fun(CMyclass obj) // 函数的参数是类CMyclass 的对象,会调用复制构造函数
{
cout << "fun" << endl;
}
- 这样的函数,调用时生成形参会引发复制构造函数调用,开销比较大。
- 所以可以考虑使用
CMyclass&
引用类型作为参数。 - 如果希望确保实参的值在函数中不应被改变,那么可以加上
const
关键字:
所以可以写成这样:
void fun(const CMyclass & obj) {
// 函数中任何试图obj值的语句都将是成非法
}
热门推荐
高尿酸大多是吃出来的?3种痛风最爱的食物,你可能天天吃
掌握理财基本原则,轻松管理财富实现财务自由
希腊史11:德谟克利特—首个百科全书式的学者,寻求真理弄瞎双眼
最适宜人类居住的海拔是多少
果酸焕肤祛痘印治疗效果怎么样?原理、适用人群及护理全解析
中国两座世界遗产古城:丽江古城VS平遥古城,你更喜欢哪个?
2025初中学业水平考试(中考)最全介绍
1988年,神童高华健放弃国籍加入美国,结果为中国送回20位博士
高华健:加入美国国籍,本以为是忘恩负义,却带20位博士回国
手机流量卡顿怎么办?这份详细指南帮你搞定!
老年人蛛网膜下腔出血怎么诊断
安捷伦示波器滤波设置
乡镇公务员面试全攻略:从专业指导到实战技巧
满小饱肥汁米线疑似吃出壁虎头,曾一年从1亿做到近10亿
Load JS Manually
如何做到js的延时加载
伯克希尔·哈撒韦囤3250亿美元现金背后,巴菲特的逻辑是什么?
空调内机安装高度多少合适
如何掌握空调安装的要点并确保良好的使用效果?
樱花的功效与作用
家常胡萝卜做法推荐,营养又美味
六月份,如何做好一个合理的骑行计划?从这3点着手
精细磷化工在工业生产中的应用及其效率提升
如何选择乳胶漆?最实用的避坑指南!
事业部制管理模式的实施步骤有哪些
OGSM被宝洁誉为神器?
巧用一块“海绵”进行扦插繁殖,7 天即可出新根,成活率大幅提升
730纳米皮秒激光治疗雀斑疗效研究
退部申请书的撰写指南:结构、原则与注意事项
双靶抗真菌药物——真菌感染和耐药困境的破局之策