1.explicit 修饰构造函数
给构造函数加了explicit
千万别用explicit修饰带整型参数的构造 Test(int data)
就只认 Test t2(10) 不认 Test t2 = 10
#include <iostream>
using namespace std;
class A
{
public:
//这里用explicit关键词来修饰类构造函数.
explicit A(int i = 5, int j = 10)
{
m_a = i;
m_b = j;
}
private:
int m_a;
int m_b;
};
int main()
{
A s;
//这样直接赋值,会被提示错误,因为explicit抑制隐式转换的进行
s = 10;//这样会报错!!!
//当然显示转换还是可以的.
s = A(20);
system("pause");
return 0;
}
2.深拷贝,浅拷贝
C++中类的拷贝有两种:深拷贝,浅拷贝
当出现类的等号赋值时,即会调用拷贝函数
对象的成员变量占用外部资源的时候,需要重写下面两个函数,防止对象的浅拷贝问题:
拷贝构造函数
赋值函数
两个的区别
1 在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数——即浅拷贝,它能够完成成员的一一复制。当数据成员中没有指针时,浅拷贝是可行的;但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两次析构函数,而导致指针悬挂现象(野指针),所以,此时,必须采用深拷贝。
2 深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来储存数据,从而也就解决了指针悬挂的问题。简而言之,当数据成员中有指针时,必须要用深拷贝。
浅拷贝不一定是错的 但是如果对象占用了外部资源,那么浅拷贝就一定有问题
防止浅拷贝:
1.把拷贝构造和operator赋值重载函数私有化
2.利用C++11的语法,把拷贝构造和赋值函数delete掉
3.重写拷贝构造和赋值重载函数
4.对于局部的临时的对象给外部对象拷贝构造或者重载 可以定义带右值引用参数的
class CBook
{
public:
CBook(const char *n)
{
mpname = new char[strlen(n) + 1];
strcpy(mpname, n);
mcount++;
}
~CBook()
{
delete[]mpname;
mpname = nullptr;
}
CBook(const CBook&) = delete;
void operator=(const CBook&) = delete;
}
如果不写构造和析构 认为编译器生成了一个空函数的构造和析构函数
但是默认生成的类的拷贝构造和赋值函数直接做内存的浅拷贝 Test t1=t2;
例子:
比如现在要对一个栈进行拷贝,因为这个栈中的数据成员有指针(或者有数组):
int main()
{
// SeqStack init release push pop top full empty
// 1.定义一个顺序栈对象 a.SeqStack尺寸开辟内存 b.调用合适的构造函数
SeqStack stack;
// 2.以系统时间种随机数种子
srand(time(nullptr));
// 3.循环添加20个【1,100】之间的随机整数入栈
for (int i = 0; i < 20; ++i

本文详细介绍了C++中的`explicit`关键字修饰构造函数的作用,以及深拷贝和浅拷贝的概念。讨论了如何避免浅拷贝导致的问题,包括重写拷贝构造函数和赋值操作符,以及使用C++11的`delete`关键字。同时,阐述了构造函数和析构函数的功能、调用时机和生存周期,强调了析构顺序的重要性,并提醒程序员成员变量初始化应尽量在构造函数初始化列表中完成。

698

被折叠的 条评论
为什么被折叠?



