ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c++类的几种成员函数声明后必须要定义吗?

2019-07-10 14:36:40  阅读:236  来源: 互联网

标签:函数 int c++ 几种 纯虚 test CTest 定义


c++类的几种成员函数声明后必须要定义吗?

1. 构造函数和析构函数

test.h

#pragma once
class CTest
{
public:
	CTest();
	~CTest();
};

test.cpp

#include "stdafx.h"
#include "test.h"

情况一:

main.cpp

#include "stdafx.h"
#include "test.h"

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}

编译通过

[外链图片转存失败(img-dT6rg82V-1562739765618)(C:\Users\panbaoru\AppData\Roaming\Typora\typora-user-images\1562730641546.png)]

在没有实例化该类对象时,即使没有对构造函数和析构函数定义,编译通过。
(emmm我觉得这好像有点废,因为都没有用,都没有编译test.h和test.cpp

情况二:

main.cpp

int _tmain(int argc, _TCHAR* argv[])
{
	CTest test;

	return 0;
}

编译失败

[外链图片转存失败(img-F5yOPJFv-1562739765619)(C:\Users\panbaoru\AppData\Roaming\Typora\typora-user-images\1562730774806.png)]

类实例化时一定会调用构造函数和析构函数,所以当构造函数和析构函数没有定义时,链接时报错:找不到该函数定义

2. 普通成员函数

test.h

#pragma once
class CTest
{
public:
	CTest();
	~CTest();
	void test();
};

test.cpp

#include "stdafx.h"
#include "test.h"
CTest::CTest()
{

}

CTest::~CTest()
{

}

情况一:

main.cpp

int _tmain(int argc, _TCHAR* argv[])
{
	CTest test;

	return 0;
}

编译成功

因为没有调用test的test成员函数,所以链接时不会去找该定义,因此链接通过。

情况二:

main.cpp

int _tmain(int argc, _TCHAR* argv[])
{
	CTest test;
	test.test();
	return 0;
}

编译失败

[外链图片转存失败(img-akCM1Lnv-1562739765619)(C:\Users\panbaoru\AppData\Roaming\Typora\typora-user-images\1562738809749.png)]

因为调用test的test成员函数,所以链接时会去找该定义,结果没找到,因此链接报错。

3. 虚函数

test.h

#pragma once
class CTest
{
public:
	CTest();
	~CTest();
	virtual void testVirtual();
};

test.cpp

#include "stdafx.h"
#include "test.h"
CTest::CTest()
{

}

CTest::~CTest()
{

}

main.cpp

int _tmain(int argc, _TCHAR* argv[])
{
	CTest test;
	return 0;
}

编译失败

[外链图片转存失败(img-X968vU7b-1562739765619)(C:\Users\panbaoru\AppData\Roaming\Typora\typora-user-images\1562739013865.png)]

 实例化类的虚函数必须有定义,原因如下:有虚函数作为成员函数的类, 它的实例化-对象, 在运行过程分配到的内存不止是它的成员数据, 还有一个指向该类虚函数表(vtable)的指针, 虚函数表中的每个数据项都是一个虚函数的入口地址; 如果一个对象的虚函数只有声明而没有实现, 就会出现这个虚函数表找不到本应作为其数据项之一的某函数的入口地址, 虚函数表在运行前不能装载完成, 所以产生连接错误!

定义该虚函数后链接成功!

4. 纯虚函数

test.h

#pragma once
class CTest
{
public:
	CTest();
	~CTest();
	virtual void testPureVirtual() = 0;
};

test.cpp

#include "stdafx.h"
#include "test.h"
CTest::CTest()
{

}

CTest::~CTest()
{

}

main.cpp

int _tmain(int argc, _TCHAR* argv[])
{
	CTest test;
	return 0;
}

编译报错

[外链图片转存失败(img-B92dv1Ue-1562739765620)(C:\Users\panbaoru\AppData\Roaming\Typora\typora-user-images\1562739654824.png)]

包含纯虚函数的类是抽象类,抽象类不可以实例化,否则报错。原因如下:
纯虚函数出现在接口类中,并赋值为0,不要为该函数分配函数地址,从而阻止类的实例化!纯虚函数是没有定义的,如果实现了也不是纯虚函数啦!

总结

  1. 需要实例化类的虚函数必须有定义,而仅仅定义带有虚函数的类且虚函数没有实现,该类编译是可以通过的!
  2. 纯虚函数出现在接口类中,并赋值为0,不要为该函数分配函数地址,从而阻止类的实例化!纯虚函数是没有定义的,如果实现了也不是纯虚函数啦!
  3. 一般的成员函数可以只有声明,前提是在应用中不能调用该函数,否则会因找不到定义产生连接错误!

函数地址,从而阻止类的实例化!纯虚函数是没有定义的,如果实现了也不是纯虚函数啦!


#### 总结

1. 需要实例化类的虚函数必须有定义,而仅仅定义带有虚函数的类且虚函数没有实现,该类编译是可以通过的!
2.  纯虚函数出现在接口类中,并赋值为0,不要为该函数分配函数地址,从而阻止类的实例化!纯虚函数是没有定义的,如果实现了也不是纯虚函数啦!
3.  一般的成员函数可以只有声明,前提是在应用中不能调用该函数,否则会因找不到定义产生连接错误!

标签:函数,int,c++,几种,纯虚,test,CTest,定义
来源: https://blog.csdn.net/Quellaaa/article/details/95333680

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有