C++编译器编译时产生的默认函数

       一个空类,经过C++编译器编译后会产生一些默认的函数,那具体有哪些函数呢,根据资料显示有6个,分别为默认构造函数,拷贝构造函数,析构函数,赋值运算符取址运算符,取地运算符(const版本)。
使用时的调用如下:

#ifndef CTEST_HH_
#define CTEST_HH_

#include <iosfwd>

class CTest
{
public:
	CTest();				//默认构造函数
	~CTest();				//析构函数
	CTest(const CTest& str);		//拷贝构造函数
	CTest* operator &();			//取地址运行符(非const)
	const CTest* operator &() const;	//取地址运行符(const)
	CTest& operator =(const CTest& str);	//赋值运行符


	CTest(const char *s);			//有参构造函数
	friend std::ostream& operator << (std::ostream& os, const CTest& str);
	char* str;                              //存储数据

private:
	//char* str;//存储数据
	int len;                                //字符串长度
};

#endif // CTEST_HH_

#include "CTest.h"
#include <cstring>
#include <iostream>

CTest::CTest()								//默认构造函数
{
	std::cout << "默认构造函数================" << this << std::endl;
	len = 0;
	str = new char[len + 1];
	str[0] = '\0';
}
CTest::~CTest()								//析构函数
{
	std::cout << "析构函数=====================" << this << "  str=" << str << std::endl;
	delete[]str;
}

CTest::CTest(const CTest& st)				//拷贝构造函数
{
	std::cout << "拷贝构造函数=================" << this << "  str=" << st.str << std::endl;
	if (this == &st)//这里会调用取地址运算符const
		return;
	delete []str;

	len = st.len;
	str = new char[len + 1];
	strncpy_s(str, (len + 1), st.str, len + 1);
}

CTest* CTest::operator &()					//取地址运行符(非const)
{
	std::cout << "取地址运算符(非const)=======" << this << std::endl;
	return this;
}

const CTest* CTest::operator &() const		//取地址运算符(const)
{
	std::cout << "取地址运算符(const)===========" << this << std::endl;
	return this;
}


CTest& CTest::operator =(const CTest& st)	//赋值运算符
{
	std::cout << "赋值运算符================str=" << st.str << std::endl;
	if (this == &st)//这里会调用取地址运算符const
		return *this;
	delete[]str;
	len = st.len;
	str = new char[len + 1];
	strcpy_s(str, (len + 1), st.str);
	//strcpy(str, st.str);
	return *this;
}

CTest::CTest(const char* s)					//有参构造函数
{
	std::cout << "重载构造函数=================" << this << "  str=" << s << std::endl;
	len = strlen(s);
	str = new char[len + 1];
	strcpy_s(str,(len + 1), s);
	//strcpy(str, s);
}

std::ostream& operator << (std::ostream& os, const CTest& str)
{
	os << str.str;
	return os;
}

//main.cpp
#include "CTest.h"
#include <iostream>

int main()
{
	CTest test1;//默认构造函数
	std::cout << "1=======================================\n";
	CTest test2("camle");//调用重载构造函数
	std::cout << "2=======================================\n";
	test1 = test2;//赋值运算符  (如果没有赋值运算符重载,test1和test2的str指向同一块内存,会释放两次)
	std::cout << "test1====" << test1 << "  test2===" << test2 << "\n";
	std::cout << "3=======================================\n";
	CTest* test3 = new CTest(test2);//调用拷贝构造函数 (如果没有重载拷贝构造函数,下面的delete test4析构时会把test2的内存释放掉,test2再析构时就会出错)
	std::cout << "4=======================================\n";
	CTest* test4 = &test2;//调用取地址运算符
	std::cout << "5=======================================\n";
	
	const CTest test5;//调用取地址运算符(const)
	&test5;
	std::cout << "7=======================================\n";

	delete test3;//调用析构函数
	std::cout << "hello world\n";
	return 0;
}

大部分情况下,我们不需要重载这些函数,但如果类里有内存的申请变化,就需要重载部分函数,例如,如果不重载=赋值运算符,

test1 = test2;//赋值运算符 

test1和test2的str指向同一块内存,析构时这块内存会释放两次

如果不重载拷贝构造函数,

则delete test3; 释放的是test2的空间,test2的空间会多次释放

注意:

1.有些书上只是简单的介绍了前四个函数。没有提及后面这两个函数。但后面这两个函数也是空类的默认函数。
另外需要注意的是,只有当实际使用这些函数的时候,编译器才会去定义它们。


2.自定义的拷贝构造函数不仅会覆盖默认的拷贝构造函数,也会覆盖默认的构造函数。
下面的代码是编译不过的,用户必须再显式的定义一个无参的构造函数。
 

class Empty {
public:
    Empty(const Empty& e) //拷贝构造函数
    {
    }

};

int main(int argc, char** argv)
{
    Empty a;
    return 0;
}

编译时报错

严重性    代码    说明    项目    文件    行    禁止显示状态
错误    C2512    “Empty”: 没有合适的默认构造函数可用   

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值