首页 > 编程语言 >C++中声明和定义的注意事项

C++中声明和定义的注意事项

时间:2024-10-25 11:22:10浏览次数:3  
标签:定义 sittingRoom 注意事项 C++ person2 Goodfriend1 bedRoom 声明

前言:最近学习完C++的一些基本知识之后,开始了C++核心编程内容的学习。学习到了类和对象的部分。其中,在昨天学到友元的时候,遇到了一个问题,我就写了两个类,只不过这次把类的成员函数的实现写在了类外。本来想着的是,反正后面学习会把声明和定义分开写成.h和.cpp文件,就寻思先试试把定义分出来写提前熟悉一下。没想到,程序运行结果报错,然后我又把类外实现改回了类内实现,还是报错!简直小搞我一波。

这个案列主要是讲成员函数做友元。先定义分别定义两个类,在一个类中添加另一个类的成员函数做友元,让另一个类通过成员函数访问该类的私有属性。首先给出常规思维的代码:

#include<iostream>
using namespace std;
#include< string>


class person2 ;//声明一个person类

class Goodfriend1
	{
public:
	Goodfriend1()
    {
    //创建一个对象
	 pers = new person2; 
    }
	void visit1()//让成员函数访问person2中的私有属性 
    {
    cout << "好朋友在访问" <<  pers->sittingRoom << endl;
	cout << "好朋友在访问" << pers->bedRoom << endl;
    }	
    void visit2()//不可以访问person2中的私有属性
    {
    //测试函数
    cout << "好朋友在访问" <<  pers->sittingRoom << endl;
	cout << "好朋友在访问" << pers->bedRoom << endl;
    }
public:
	person2* pers;
	};

class person2
 	{
	friend void Goodfriend1::visit1();
public:	
	person2()//无参构造声明
    {
    this->sittingRoom = "客厅";
	this->bedRoom = "卧室";
    }
public:
	string sittingRoom;
private:
	string bedRoom;
	};

void TEST02()
	{
	Goodfriend1	gg;
	gg.visit1();
    //gg.visit2();
	}

int main()
	{
	TEST02();

	system("pause");
	return 0;
	}

常规思维的写法就是这样,但是大家去运行程序。会惊奇的发现,程序跑不通!!!他会告诉我们pers这个对象没有构造函数!是不是大眼瞪小眼,挺懵逼的。

这个地方我个人的理解是这样的:程序中的代码是有着执行顺序的。如果我们在声明两个类的同时并且在类中进行定义,当两个类中互相有对方的类中成员的声明语句时。因为已经在类中进行了定义,所以编译器会顺着代码依次执行,当类中出现的别的类中的成员声明语句时,编译器找不到相应的定义就会报错!在这种情况下我们必须将各个类的声明和定义分开编写!编译器才知道我们的意思。修改后的代码如下:

#include<iostream>
using namespace std;
#include< string>


class person2 ;//声明一个person类

class Goodfriend1
	{
public:
	Goodfriend1();
	void visit1();//让成员函数访问person2中的私有属性 
	void visit2();//测试函数
public:
	person2* pers;
	};

class person2
 	{
	friend void Goodfriend1::visit1();
public:	
	person2();//无参构造声明
public:
	string sittingRoom;
private:
	string bedRoom;
	};

 person2::person2() //类外实现person类的无参构造函数
	{
	this->sittingRoom = "客厅";
	this->bedRoom = "卧室";
	}	

Goodfriend1::Goodfriend1()//类外实现Goodfriend类构造函数
	{
	//创建一个对象
	 pers = new person2; 
	}
void Goodfriend1:: visit1()
	{
	cout << "好朋友在访问" <<  pers->sittingRoom << endl;
	cout << "好朋友在访问" << pers->bedRoom << endl;
	}
//void Goodfriend1:: visit2()
	//{
	//cout << "好朋友在访问" <<  pers->sittingRoom << endl;
	//cout << "好朋友在访问" << pers->bedRoom << endl;
	//}

void TEST02()
	{
	Goodfriend1	gg;
	gg.visit1();
    //gg.visit2();
	}

int main()
	{
	TEST02();

	system("pause");
	return 0;
	}

运行代码就显示正常拉。

最终总结就是:当两个类中互相有着对方类中成员的声明时,需要将全部声明和相关的定义分开编写,这样编译器才能正确理解我们的意图。 

写到这里突然想起来还没解释开头的时候我说写在类外实现还是报错的原因。

这里其实就比较呆了,我是把每个类的类外定义紧接着写在类的声明下的。也就是类声明,类定义,类声明,类定义的顺序。因为c++要求声明之间不可以出现定义,所以函数还是报错了。所以经过此次教训后,要学会把所有的全部的声明和全部的定义分开来写,我想这也是声明写在.h文件和定义写在.cpp文件的原因吧。

标签:定义,sittingRoom,注意事项,C++,person2,Goodfriend1,bedRoom,声明
From: https://blog.csdn.net/weixin_55017074/article/details/143171680

相关文章

  • C++左移运算符重载的理解
    最近学习C++学到了运算符重载的部分,大部分运算符重载都就可以实现作为类中成员函数和全局函数进行重载实现,而左移运算符“<<”却只支持全局函数进行重载。这是是为什么呢?我来谈谈我的理解。大家首先随便用cout输出一下,然后点击cout然后右键选择转到声明:我们会看到如下图显示......
  • C++ 内存管理 堆和栈、内存泄漏、内存分配、指针与内存、智能指针、malloc和free、new
    1.堆和栈的区别1.**管理方式**:-**栈**:自动管理。当函数调用时,局部变量会自动分配在栈上。函数执行完毕后,这些变量会自动释放。-**堆**:手动管理。程序员需要使用`new`来在堆上分配内存,并在不再需要时使用`delete`来释放。2.**使用方式和寿命**:-**栈**:用......
  • 大华乐橙设备私有平台EasyCVR私有化部署视频平台监控摄像机安装注意事项与具体步骤
    在当今数字化时代,视频监控已成为保障安全的重要手段。监控摄像机的安装和配置是一个涉及多个步骤的细致过程。本文将探讨在安装过程中需要注意的事项以及具体的安装步骤,确保用户能够高效、安全地部署监控系统。首先,确保监控摄像机的选址合理,避免监控盲区,并考虑到光线变化对图像质......
  • C++ 好用的包管理工具--vcpkg
    https://blog.csdn.net/lizhichao410/article/details/132339064 背景Windows下开发C/C++程序,少不了编译开源的第三方库,使用这些库开发极大的方便了程序员,使得我们不必重复造轮子。由于开源库绝大部分都来源于Linux系统、将其移植到Windows的VC开发环境下编译比较复......
  • 【32】C++流
    C++流IO: 向设备输入数据和输出数据C++的IO流设备: 文件控制台特定的数据类型(stringstream)c++中,必须通过特定的已经定义好的类, 来处理IO(输入输出)读写文件:文件流文件流: 对文件进行读写操作头文件:  <fstream>类库:   ifstream   对文件输入(读......
  • C++的汉诺塔
    汉诺塔(TowerofHanoi)是一个经典的递归问题。问题的描述如下:有三根杆(通常称为A、B、C),以及一系列大小不同、穿在一根杆上的圆盘。这些圆盘可以滑动到任何一根杆上,但是每次只能移动一个圆盘,且不能将较大的圆盘放在较小的圆盘上。目标是将所有圆盘从杆A移动到杆C。下......
  • springboot巡更系统--10192(免费领源码)可做计算机毕业设计JAVA、PHP、爬虫、APP、小程
    摘 要目前,在日常生活中随处可见社区巡更人员对特定的区域进行定期或者不定期的安全巡查管理。包括勤前训示、必到点签到、巡更路线等,各项勤务工作均由巡更员本人在执勤日志本中手工填写,且工作点分散,不利于统一监管,存在信息化手段不足,勤务信息获取、输入复杂,监管信息不能实时......
  • 【最新原创毕设】基于JSP+SSM的民宿预约平台+79197(免费领源码)可做计算机毕业设计JAVA
    目录摘要1绪论1.1选题背景与意义1.2国内外研究现状2系统分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3法律可行性分析2.2系统流程分析2.2.1添加信息流程2.2.2修改信息流程2.2.3删除信息流程2.3 系统功能分析2.3.1功能性分析2.3......
  • C++中的内存管理
    下图是C++的内存储存管理的方式  由图不难得知,局部变量是储存在栈中的,而malloc,calloc,realloc开辟出来的空间是储存在堆中的,全局数据和静态变量储存在数据段中,也叫静态区.代码段存的是可执行代码和只读常量。 C语言中动态内存管理方式:malloc/calloc/realloc/f......
  • C++模板
    模板初阶如何实现一个通用的加法函数?我们可以类似这样使用函数重载的方法进行编写intsum(int&a,int&b){ returna+b;}doublesum(double&a,double&b){ returna+b;}使用函数重载虽然可以实现,但是有一下几个不好的地方:1.重载的函数仅仅是......